深入探究Spring底层核心原理

 更新时间:2023年04月19日 10:34:08   作者:胡尚  
理解IOC与AOP的实现机制,优化应用性能与可维护性。Spring通过IOC容器管理Bean,AOP实现切面编程,支持事务管理、ORM框架等。深入理解Spring原理,可以帮助我们更好地使用Spring框架,提高开发效率与质量

Spring底层核心原理

下面这几行代码是一个Spring的入门代码,第一行是通过java配置类 注解的方式创建一个Spring容器,第二行是通过XML配置文件的方式创建一个Spring容器

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

最后两行代码就是从Spring容器中拿一个Bean对象并执行方法。那么Spring是如何创建一个Bean对象的嘞?

Bean的生命周期

  • 推断构造方法,并执行得到普通对象
  • 依赖注入
  • aware回调
  • 初始化前

执行BeanPostProcessor接口中的postProcessBeforeInitialization()方法

  • 初始化

执行有@PostConstruct注解的方法执行

InitializingBean接口中的afterPropertiesSet()方法

执行XML配置文件中init-method属性指定的方法

  • 初始化后

执行BeanPostProcessor接口中的postProcessAfterInitialization()方法

  • 普通对象/代理对象 存入容器中
  • 使用
  • 销毁

执行DisposableBean接口的destroy()方法

@PreDestroy注解的方法

XML 配置文件中destroy-method属性指定的方法

推断构造方法

如果没有写构造方法,那么Spring会执行默认空参的构造方法

如果显示写了一个构造方法,那么Spring就会使用这个构造方法,构造方法中如果有参数那么会进行依赖注入

如果显示写了多个构造方法并有空参的构造方法时,会执行空参的构造方法

如果显示写了多个构造方法没有空参的构造方法时,运行时会报错。解决方法是在要执行的构造方法上加@Autowired注解

AOP原理

cjlib和jdk两种动态代理的实现都是有一个target属性来存储普通对象,代理对象中重写要执行的方法,首先执行增强逻辑,然后通过target属性去执行目标方法。伪代码如下:

public class UserServiceProxy extends UserService{
    private UserService target;
    public void test(){
        // TODO 增强业务
        target.test();
        // TODO 增强业务
    }
}

那么如何判断一个Bean是否需要进行AOP创建一个普通对象嘞?

  • 遍历所有有@Aspect注解的切面Bean
  • 遍历所有的方法
  • 判断方法上的切点表达式是否和当前正在创建的Bean匹配
  • 如果匹配则把这个切面中增强方法存入一个Map缓存中

真正要执行代理对象的方法时会从缓存中取出相应的增强逻辑来执行,再去执行目标方法。

Spring事务

Spring中如果要使用事务需要配置一个JdbcTemplate和一个事务管理器,它们俩都需要配置DataSource。

@ComponentScan("com.hs")
@Configuration
public class AppConfig {
   @Bean
   public JdbcTemplate jdbcTemplate() {
      return new JdbcTemplate(dataSource());
   }
   @Bean
   public PlatformTransactionManager transactionManager() {
      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
      transactionManager.setDataSource(dataSource());
      return transactionManager;
   }
   @Bean
   public DataSource dataSource() {
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/hs?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai");
      dataSource.setUsername("root");
      dataSource.setPassword("123456");
      return dataSource;
   }
}

Spring事务大致执行流程如下:

  • 判断要执行的方法上是否存在@Transcational注解
  • 如果存在则通过事务管理器创建一个connection连接对象
  • autoCommit设置为false
  • 去执行目标方法target.method()
  • 如果出现了异常则回滚rollback(),没有异常则提交commit()

如果上面的配置类中不加@Configuration注解,那么Spring的事务会失效。原因如下:

JdbcTemplate和事务管理器都需要DataSource,都会调用dataSource()获取。如果不加@Configuration注解,那么他们俩获取的DataSource就不是同一个。

代理对象中操作的是事务管理器的连接对象,而业务方法却是使用的JdbcTemplate,所以就导致了Spring事务失效。

而如果加上了@Configuration注解,在调用dataSource()时会先去Spring容器中找DataSource,如果没找到才回去调用方法创建一个。

到此这篇关于深入探究Spring底层核心原理的文章就介绍到这了,更多相关Spring底层原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot中动态数据源配置与使用详解

    SpringBoot中动态数据源配置与使用详解

    在现代应用中,处理多数据源是常见的需求,在 Spring Boot 中,这样的需求可以通过动态数据源来轻松实现,本篇博客将详细介绍如何在 Spring Boot 中配置和使用动态数据源,并演示如何切换到指定的数据源,需要的朋友可以参考下
    2024-10-10
  • idea中的lombok不生效的四种解决方法

    idea中的lombok不生效的四种解决方法

    Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,本文将详细给大家介绍idea中的lombok不生效的四种解决方法,需要的朋友可以参考下
    2023-05-05
  • 利用java操作Excel文件的方法

    利用java操作Excel文件的方法

    以下是对利用java操作Excel文件的方法进行了详细的介绍,需要的朋友可以过来参考下
    2013-09-09
  • java 设计模式之适配器模式的详解

    java 设计模式之适配器模式的详解

    这篇文章主要介绍了java 设计模式之适配器模式的详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • 浅谈Java中的克隆close()和赋值引用的区别

    浅谈Java中的克隆close()和赋值引用的区别

    下面小编就为大家带来一篇浅谈Java中的克隆close()和赋值引用的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • spring boot实现过滤器和拦截器demo

    spring boot实现过滤器和拦截器demo

    本篇文章主要介绍了spring boot实现过滤器和拦截器demo ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Java深入探究Object类的方法

    Java深入探究Object类的方法

    java继承中说到的Object类是java中一个特殊的类,所有的类都是直接或者间接的继承自Object类,即如果某个类没有使用extends关键字则默认是java.lang.Object类的子类,所以所有的类都可以使用Object类中定义的方法,下面介绍Object类的常用方法
    2022-05-05
  • BigDecimal divide除法除不尽报错的问题及解决

    BigDecimal divide除法除不尽报错的问题及解决

    这篇文章主要介绍了BigDecimal divide除法除不尽报错的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java后台实现微信支付和微信退款

    Java后台实现微信支付和微信退款

    这篇文章主要介绍了Java后台实现微信支付和微信退款,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Java中的关键字_动力节点Java学院整理

    Java中的关键字_动力节点Java学院整理

    关键字也称为保留字,是指Java语言中规定了特定含义的标示符。对于保留字,用户只能按照系统规定的方式使用,不能自行定义
    2017-04-04

最新评论