-
利用构造方法创建对象
-
Spring 判断对象是否被 @Autowired @Component @Service 等注解
-
Spring 判断类是否实现某些初始化接口,如:
{@link org.springframework.beans.factory.BeanNameAware#setBeanName(String)}
{@link org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader)}
{@link org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(BeanFactory)}
如果实现了?
Spring 将会调用这些方法并传入相应的参数。
- 然后 Spring 会判断对象是否存在被 @PostConstruct 注解,存在?调用此方法。(初始化前)
- 紧接着 Spring 会判断是否实现接口
{@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
如果实现了?
调用此接口(初始化)
- 最后,判断对象是否需要进行 AOP操作
需要? 得到的对象是 UserService 类的代理对象
不需要? 得到的对象是 UserService 类的构造方法创建的对象
此处,可能会有小伙伴疑问?构造方法存在多个时,Spring 又是怎么选择的呢?AOP 流程又是怎么样的?
构造方法的选择
-
如果一个类只存在一个构造方法,不管是否存在参数,Spring 会选择这个。
-
如果存在多个构造方法
- 是否存在无参构造方法,存在则选择
- 不存在无参构造方法,报错
注意:在选择中,如果存在某个构造方法上加了 @Autowired 注解,那么 Spring 会选择该构造方法
AOP 流程
如何判断对象是否需要进行 AOP 操作?
我总结了一下:一面二增三匹配
- 先找出切面
- 遍历切面的所有增强 @Before 前置、@After 后置、@Around 环绕 等增强
- 切点 和 Bean 对象类型是否匹配,如果匹配则进行 AOP 操作
利用 cglib 进行 AOP 流程:
- 生成代理类 UserServiceProxy
- 判断代理类是否重写接口方法
- 代理类里存在一个 target 属性,属性值为 被代理的对象
- 代理类执行逻辑:执行切面逻辑;调用 target 相应方法
Bean 创建之后
- 如果 Bean 的作用域(Scope)为单例,将 bean 对象存放到 Map<beanName:String, Object:Bean> 对象中(单例池),通过 getBean(beanName:String) 获取。
- 如果 Bean 的作用域 (Scope)为原型,通过 getBean(beanName:String)获取,会再次执行上述流程,得到一个新 Bean 对象。
拓展
Spring 事务
当我们在某个方法加上 @Transactional 注解,表示该方法开启 Spring 事务。而方法所在的 Bean 会是代理对象
代理对象执行步骤:
- 判断当前是否存在 @Transactional 注解
- 如果存在,则利用 事务管理器 新建一个数据库连接
- 修改数据库连接 autocommit 为 false
- 执行 target 对象相应方法
- 执行完毕,判断是否存在异常?存在回滚事务,不存在提交事务
喜欢本博主的文章欢迎关注我的公众号【我的极简博客】,阅读更多文章。
网友评论