Spring 的工厂类
Bean实例化的三种方式
- 使用类构造器实例化(默认无参数)
- 使用静态工厂方法实例化(简单工厂模式)
- 使用实例工厂方法实例化(工厂方法模式)
<!--Bean的实例化的三种方式-->
<!--第一种:无参构造器的方式-->
<bean id="bean1" class="com.chen.web.bean.Bean1"></bean>
<!--第二种:静态工厂的方式-->
<bean id="bean2" class="com.chen.web.bean.Bean2Factory" factory-method="createBean2"></bean>
<!--第三种:实例工厂的方式-->
<bean id="bean3Factory" class="com.chen.web.bean.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"></bean>
Bean的实例化三种方式:采用无参数的构造方法的方式
public class Bean1 {
public Bean1(){
System.out.println("Bean1被实例化了");
}
}
Bean的实例化三种方式:静态工厂实例化方式
public class Bean2 {
}
/**
* Bean2的静态工厂
*/
public class Bean2Factory {
public static Bean2 createBean2(){
System.out.println("Bean2Factory的方法已经执行了");
return new Bean2();
}
}
Bean的实例化三种方式:实例工厂实例化
public class Bean3 {
}
/**
* Bean3的实例工厂
*/
public class Bean3Factory {
public Bean3 createBean3(){
System.out.println("Bean3Factory执行了.");
return new Bean3();
}
}
测试
public class BeanTest {
@Test
public void Bean1Test(){
//创建Spring的工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过工厂获取类
Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
}
@Test
public void Bean2Test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
}
@Test
public void Bean3Test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
}
}
一般都采用无参数的构造方法的方式
Bean的作用域
- scope="singleton":在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在(默认)
- scope="prototype":每次调用getBean()时都会返回一个新的实例
Bean的生命周期
- bean对象实例化
- 封装属性
- 如果Bean实现BeanNameAware 执行 setBeanName
- 如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂setBeanFactory 或者上下文对象 setApplicationContext
- 如果存在类实现 BeanPostProcessor,执行postProcessBeforeInitialization
BeanPostProcessor 可以在生成类的过程中对类进行代理并且可以对里面的方法增强 - 如果Bean实现InitializingBean 执行 afterPropertiesSet
- 调用<bean init-method="setup"> 指定初始化方法:setup()
如果存在类实现BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization - 执行业务处理
- 如果Bean实现 DisposableBean 执行 destroy
- 调用<bean destroy-method="teardown"> 指定销毁方法:teardown()
<bean id="user" class="com.chen.web.bean.User" init-method="setup" destroy-method="teardown">
<property name="name" value="小米"></property>
</bean>
<bean class="com.chen.web.bean.MyBeanPostProcessor"/>
public class User implements BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean {
private String name;
public User(){
System.out.println("第一步:初始化.");
}
public void setName(String name) {
System.out.println("第二步:设置属性");
this.name = name;
}
@Override
public void setBeanName(String name) {
System.out.println("第三步:设置Bean的名称"+name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:了解工厂信息");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后");
}
public void setup(){
System.out.println("第七步:User被初始化了");
}
public void run(){
System.out.println("第九步:执行业务方法");
}
@Override
public void destroy() throws Exception {
System.out.println("第十步:执行Spring的销毁方法");
}
public void teardown(){
System.out.println("第十一步:User被销毁了");
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:初始化前方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("第八步:初始化后方法");
return bean;
}
}
测试
@Test
public void BeanLifeTest(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) applicationContext.getBean("user");
user.run();
applicationContext.close();
}
Spring的属性注入
对于类成员变量,注入方式有 构造函数注入 和 属性setter方法注入
构造函数注入
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<bean id="person" class="com.chen.web.bean.Person">
<constructor-arg name="name" value="巴西"/>
<constructor-arg name="age" value="8"/>
</bean>
测试
@Test
public void BeanIntoTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) applicationContext.getBean("person");
System.out.println(person);
}
输出:Person{name='巴西', age=8}
属性setter方法注入
public class People {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<bean id="people" class="com.chen.web.bean.People">
<property name="name" value="德国"/>
<property name="age" value="1"/>
</bean>
测试
@Test
public void BeanInTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = (People) applicationContext.getBean("people");
System.out.println(people);
}
类对象的属性注入
<bean id="people" class="com.chen.web.bean.People">
<property name="name" value="德国"/>
<property name="age" value="1"/>
<property name="grade" ref="score"/>
</bean>
<bean id="score" class="com.chen.web.bean.Score">
<property name="name" value="赢"/>
</bean>
p名称空间属性注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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="person" class="com.chen.web.bean.Person" p:name="大黄" p:age="34" p:cat-ref="cat"/>
<bean id="cat" class="com.chen.web.bean.Cat" p:name="小黄"/>
SpEL属性注入:spring表达式语言,对依赖注入进行简化
<bean id="" value="#{表达式}">
语法:#{}
语法:#{‘hello’} :使用字符串
语法:#{id}: 使 用 另 一 个 bean
语法:#{id.method()}: 使用指定名属性,并使用方法
语法:#{T( java.lang.Math).PI}: 使用静态字段或方法