一、Bean的配置
把Spring看做一個大型工廠,其作用便是生產並管理Spring容器中的Bean。若想要使用該工廠,則常常使用XML文件來對Spring的配置文件進行配置,註冊並管理Bean之間的依賴關係。
1. 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--每一個<bean>子元素定義了一個Bean,並描述了該Bean如何被裝配到Spring容器中-->
<bean id="xxx" class="xxx.xxx">
</bean>
</beans>
2. bean元素的常用屬性及其子元素:
二、Bean 的實例化
1. 三種方式:構造器實例化(最常用)、靜態工廠方式實例化和實例工廠方式實例化。
- 構造器實例化:Spring容器通過Bean對應類中默認的無參構造方法來實例化Bean。
- 靜態工廠方式實例化:創建一個靜態工廠的方法來創建Bean的實例,Bean配置中的class屬性所指定的不再是Bean實例的實現類,而是靜態工廠類,同時還需要使用factory-method屬性來指定所創建的靜態工廠方法。
- 實例工廠方式實例化:在工廠類中不再使用靜態方法創建Bean實例,而是採用直接創建Bean實例的方式,在配置文件中,通過factory-bean屬性指向配置的實例工廠,然後使用factory-method屬性確定使用工廠中的哪個方法。
2. 代碼
-
構造器實例化
-
Bean1.java
public class Bean1 {}
- beans1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean1" class="constructor.Bean1">
</bean>
</beans>
- InstanceTest1.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest1 {
public static void main(String[] args) {
String xmlPath = "constructor/beans1.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
System.out.println(bean1);
}
}
- 靜態工廠方式實例化
- Bean2.java
public class Bean2 {}
- MyBean2Factory.java
public class MyBean2Factory {
//使用工廠創建Bean2實例
public static Bean2 createBean() {
return new Bean2();
}
}
- bean2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean2" class="static_factory.MyBean2Factory" factory-method="createBean">
</bean>
</beans>
- InstanceTest2.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest2 {
public static void main(String[] args) {
String xmlPath = "static_factory/beans2.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");
System.out.println(bean2);
}
}
- 實例工廠方式實例化
- Bean3.java
public class Bean3 {}
- MyBean3Factory.java
public class MyBean3Factory {
public MyBean3Factory() {
System.out.println("bean3 工廠實例化");
}
//創建Bean3實例的方法
public Bean3 createBean() {
return new Bean3();
}
}
- beans3.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置工廠 -->
<bean id="myBean3Factory" class="factory.MyBean3Factory">
</bean>
<!-- 使用factory-bean屬性指向配置的實例工廠,
使用factory-method屬性確定使用工廠中的哪個方法 -->
<bean id="bean3" factory-bean="myBean3Factory" factory-method="createBean">
</bean>
</beans>
- InstanceTest3.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest3 {
public static void main(String[] args) {
String xmlPath = "factory/beans3.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Bean3 bean3 = (Bean3)applicationContext.getBean("bean3");
System.out.println(bean3);
}
}
三、Bean的作用域
1. singleton(單例)Spring容器默認的作用域,使用singleton定義的Bean在Spring容器中將只有一個實例。
2. prototype(原型)每次通過Spring容器獲取的prototype定義的Bean時。容器都將創建一個新的Bean實例。
3. request,session,globalSession,application,websocket。
四、Bean的裝配方式
Bean的裝配可以理解爲依賴關係注入,Bean的裝配方式即Bean依賴注入的方式。Spring容器支持多種形式的Bean的裝配方式,如基於XML的裝配、基於註解的裝配和自動裝配等。
1. 基於XML 的裝配 (設值注入,構造注入)
- Bean類必須提供一個默認的無參構造方法。
- Bean類必須爲需要注入的屬性提供對應的setter方法。
- User.java
import java.util.List;
public class User {
private String username;
private Integer password;
private List<String> list;
//構造注入--滿參構造函數
public User(String username, Integer password, List<String> list) {
super();
this.username = username;
this.password = password;
this.list = list;
}
//設值注入--默認空參構造函數,爲所有屬性提供setter方法
public User() {
super();
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(Integer password) {
this.password = password;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", list=" + list + "]";
}
}
- bean5.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--構造注入-->
<bean id="user1" class="assemble.User">
<!--index爲屬性的索引,value屬性用於設置注入的值-->
<constructor-arg index="0" value="tom" />
<constructor-arg index="1" value="123456" />
<constructor-arg index="2">
<list>
<value>"constructorvalue1"</value>
<value>"constructorvalue2"</value>
</list>
</constructor-arg>
</bean>
<!--設值注入-->
<bean id="user2" class="assemble.User">
<property name="username" value="張三"></property>
<property name="password" value="654321"></property>
<property name="list">
<list>
<value>"setlistvalue1"</value>
<value>"setlistvalue2"</value>
</list>
</property>
</bean>
</beans>
2. 基於註解的裝配
- UserDao.java
public interface UserDao {
public void save();
}
- UserDaoImapl.java
import org.springframework.stereotype.Repository;
@Repository("userDao") //相當於<bean id="userDao" class="UserDaoImpl" />
public class UserDaoImpl implements UserDao{
public void save() {
System.out.println("userdao...save...");
}
}
- UserService.java
public interface UserService {
public void save();
}
- UserServiceImpl.java
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource(name="userDao")//相當於<property name="userDao" ref="userDao" />
private UserDao userDao;
@Override
public void save() {
this.userDao.save();
System.out.println("userservice...save..");
}
}
- UserController.java
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
@Controller("userController")
public class UserController {
@Resource(name="userService")
private UserService userService;
public void save() {
this.userService.save();
System.out.println("userController...save...");
}
}
- beans6.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 使用context 命名空間,通知Spring掃描指定包下所有Bean類,進行註解解析 -->
<context:component-scan base-package="annotation" />
</beans>
- AnnotationTest.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationTest {
public static void main(String[] args) {
String xmlPath = "annotation/beans6.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserController uc1 = (UserController)applicationContext.getBean("userController");
uc1.save();
}
}