1. Bean的生命周期

Spring中Bean的生命周期分为两种

  • Bean创建的生命周期
  • Bean销毁的生命周期

1.1 Bean的创建生命周期

要想搞清楚Bean的生命周期,我们首先需要对Bean对象有清晰的了解

1. Bean对象和普通对象

UserService userService = (UserService)applicationContext.getBean("userService");

从中获取的就是Bean对象

UserService userService = new UserService();

使用new的方式,构建出来的就为普通对象

2. Bean的创建流程

我们都知道对象的创建都是依靠构造方法进行创建的,Spring也不例外,所以我们能得出一下流程
我们的UserService Bean对象是通过
UserService类—->得到无参构造方法—->获取到普通对象—->经过一系列处理—->Bean对象
那么要想知道在普通对象和Bean对象之间,进行了那些操作,我们可以再详细看一看

//先创建OrderService类
@Component
public class OrderService {
}
//再创建UserService类
@Component
public class UserService {
    @Autowired
    private OrderService orderService;
    public void test() {
        System.out.println(orderService);
    }
}
//在Test打印输出
public class Test {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.test();
        UserService userService1 = new UserService();
        userService1.test();
    }
}

结果为

com.zhn.service.OrderService@647fd8ce
null
可见,普通对象和Bean对象中,区别就是,属性有没有值
也就是说
普通对象经过依赖注入后,便可以得到Bean对象

3. Spring如何进行依赖注入

Spring创建对象后,会扫描该类属性中,有没有@Autowired或者@Resource注解,如果有,spring就会给该属性赋值

那么是从哪里找呢,实际上,在Spring创建完Bean对象后,都会将它放入使用Map构建的单例池中(Map<beanName,Bean对象>),等到下一次调用会先从该Map池中寻找相应的Bean(查找方式:先按照类型匹配Bean,再按照名字寻找Bean),如果有,则会直接拿到使用,如果没有则会重走下面的步骤:
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->????—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池
当Bean被放入单例池中以后,才能真正的被称为Bean对象

代码也可以直接使用该方式,创建Bean对象

Object o = new UserService();
applicationContext.getBeanFactory().registerSingleton("xxx",o);

创建一个beanName为xxx的,Object o的Bean对象

4. 底层源码实现

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	Assert.notNull(beanName, "Bean name must not be null");
	Assert.notNull(singletonObject, "Singleton object must not be null");
	synchronized (this.singletonObjects) {
		Object oldObject = this.singletonObjects.get(beanName);
		if (oldObject != null) {
			throw new IllegalStateException("Could not register object [" + singletonObject +
					"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
		}
		//添加Bean
		addSingleton(beanName, singletonObject);
	}
}
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		//将Bean put到Map中
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}
//Map结构
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

5.Bean中的方法,Spring如何管理

需要在类中实现InitializingBean这个接口,重写afterPropertiesSet(),则Spring会在Bean初始化完成之前,调用该方法

@Component
public class UserService implements InitializingBean {
    @Autowired
    private OrderService orderService;
    public void test() {
        System.out.println(orderService);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Spring处理的方法执行了");
    }
}

再次执行下面代码

public class Test {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.test();
        System.out.println("---------------分割线------------------");
        UserService userService1 = new UserService();
        userService1.test();

    }
}

结果

Spring处理的方法执行了
com.zhn.service.OrderService@291ae
—————分割线——————
null
可见仍旧只有Bean对象才会执行该方法

那么Bean的创建流程可以完善为
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->afterPropertiesSet()—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池

那么afterPropertiesSet()过程是如何判断,Bean需不需要执行函数呢?

使用bean instance of InitializingBean,判断是否实现该接口

如果实现该接口,则对bean进行强制转化,执行afterPropertiesSet()

((InitializingBean)bean).afterPropertiesSet()
完成了Bean的初始化

6. Bean初始化后(AOP)

Bean的流程完善为
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->afterPropertiesSet()—->初始化后(AOP)—->代理对象—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池

AOP后 Bean对象到底是一个什么对象
代理对象?
还是Bean的普通对象?

举例


//被代理对象
@Component
public class UserService  {
    @Autowired
    private OrderService orderService;
    public void test() {
        System.out.println(orderService);
    }

}
//一般逻辑
//代理对象
class UserServiceProxy extends UserService
{
	public void test(){
		//执行切面逻辑
		super.test();
		//打印出来为null
	}
}

//Spring逻辑
//代理对象
class UserServiceProxy extends UserService
{
	UserService target;
	public void test(){
		//执行切面逻辑
		//target.test()   //Uservice普通对象.test() 打印orderService属性
		//可以打印出来值
	}
}

target存放的为依赖注入后的普通对象,orderService有值
代理对象UserServiceProxy OrderService无值

其中由于进行AOP,所以userService拿到的值应该为userService的代理对象
代理对象中OrderService值为空
点击运行后

zhnBefore
com.zhn.service.OrderService@3f1d2e23
—————分割线——————
OrderService又输出出来了值
说明 执行Test方法的为经过依赖注入后的普通对象,
AOP执行流程就很清楚了,先是代理对象执行重写的test方法,然后是进行AOP的增强操作,执行结束后,依赖注入后的普通对象再执行自身的test方法