基於xml與annotation的bean註冊

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();
		
	}

測試結果:


現在看看基於註解的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:

再看配置類,它有@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:


除了spring它自己的bean,剩餘的都是我們加了註解要求spring管理的bean。

發佈了27 篇原創文章 · 獲贊 28 · 訪問量 1972
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章