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