欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于xml与annotation的bean注册

程序员文章站 2022-05-29 15:20:30
...

spring就是个大工厂,它管理和生产对象。

我们最初是通过xml来完成DI的。

我们有个entity:

package spring_annotation.entity;

import org.springframework.stereotype.Component;


public class User {

	private Integer age;
	private String name;
	private String from;

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getFrom() {
		return from;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public User(Integer age, String name, String from) {
		super();
		this.age = age;
		this.name = name;
		this.from = from;
	}

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + ", from=" + from + "]";
	}

}

有个dao:

package spring_annotation.dao;

import org.springframework.stereotype.Repository;


public class UserDao {

	public void reg() {
		System.out.println("UserDao's reg()");
	}
}

还有service层:

package spring_annotation.service;

import org.springframework.stereotype.Service;

import spring_annotation.dao.UserDao;


public class UserServlet {

	private UserDao userDao;

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public void reg() {
		System.out.println("UserServlet's reg()");
		userDao.reg();
	}
}

随便举个例子。

现在我们要通过xml的配置,将这些对象交由spring管理,并为其注入值:

在类路径下配好spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
	
	<bean id="user" class="spring_annotation.entity.User"
	><property name="name" value="Lily"></property>
	<property name="age" value="15"></property>
	<property name="from" value="London"></property></bean>
	
	<bean id="userDao" class="spring_annotation.dao.UserDao"></bean>	
	<bean id="userServlet" class="spring_annotation.service.UserServlet">
	<property name="userDao"  ref="userDao"></property>
	</bean>
	
	
</beans>

我们用bean节点注册bean类,id是为了方便spring容器提取bean,class必须写全类名。我们可以用property节点为属性注入值,这其实是调用了bean中的set方法。当然你可以用有参构造(constructor-arg)为其注入值。

对于UserServlet,我们要为其中的属性userDao注入值,而userDao是个对象,所以我们要用ref属性节点ref="userDao",由此找到id为"userDao"的bean。

所以两个bean之间的依赖关系也是在配置文件中做完的。

注入值的场景很多,有为map注入值,list注入值,set注入值,还有为Properties注入数据库的基本链接信息。

还有spring动态注入,即spring El表达式(#{})。

我们写个简单的测试方法看看spring容器是否加载了这些bean:

	@Test
	public void test03() {
		ClassPathXmlApplicationContext ac = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		
		UserServlet userServlet = ac.getBean("userServlet",UserServlet.class);
		
		userServlet.reg();
		
		ac.close();
		
	}

测试结果:

基于xml与annotation的bean注册


现在看看基于注解的bean注册吧。其实你可以想到,不管是用XML还是注解,都是用反射技术来读取内容的。

我们要写个配置类,它的作用相当于之前的XML配置文件:

package spring_annotation.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import spring_annotation.entity.User;

@ComponentScan("spring_annotation")
@Configuration
public class MainConfig {

	@Bean("user02")
	public User user() {
		return new User(12, "Jack", "New York");
	}
}

这里@Configuration注解表明它是个配置类。

@Bean注解告诉容器这是要注册的bean,bean的id默认为方法名,也就是user,但是如果你指定value的值为user02,那id就为user02

写个测试类:

AnnotationConfigApplicationContext applicationContext = null; 
	
	@Before
	public void loadApplicationContext() {
		applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
	}
	
	@After
	public void closeApplicationContext() {
		applicationContext.close();
	}
	@Test
	public void test01() {
		Object user = applicationContext.getBean("user02");
		System.out.println(user);
	}

运行test01,我们就用id值拿到了bean:
基于xml与annotation的bean注册
再看配置类,它有@ComponentScan("spring_annotation"),这是自动包扫描,比起XML中的<context:component-scan base-package="xxx"></context:component-scan>要方便得多。

为User类、UserDao类、UserServlet类加上基本注解后,它们也会被纳进spring容器的管理。

@Repository
public class UserDao {

	public void reg() {
		System.out.println("UserDao's reg()");
	}
}

@Component
public class User {

	private Integer age;
	private String name;
	private String from;

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getFrom() {
		return from;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public User(Integer age, String name, String from) {
		super();
		this.age = age;
		this.name = name;
		this.from = from;
	}

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + ", from=" + from + "]";
	}

}

@Service
public class UserServlet {

	private UserDao userDao;

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public void reg() {
		System.out.println("UserServlet's reg()");
		userDao.reg();
	}
}

运行test02:

@Test 
	public void test02() {
		String[] definitionNames = applicationContext.getBeanDefinitionNames();
		for (String name : definitionNames) {
			System.out.println(name);
		}
	}

我们能拿到所有定义的bean:

基于xml与annotation的bean注册
除了spring它自己的bean,剩余的都是我们加了注解要求spring管理的bean。