luckylbl

Spring

Spring是什么

Spring 是一个轻量级的 Java 开发框架,主要用于简化企业级应用开发。它提供了以下核心功能:

  1. 依赖注入(DI):通过 IoC 容器管理对象的创建和依赖关系,减少代码耦合。
  2. 面向切面编程(AOP):允许将横切关注点(如日志、事务管理)与业务逻辑分离。
  3. 事务管理:提供声明式事务管理,简化事务处理
  4. 数据访问支持:整合了多种数据访问技术(如 JDBC、JPA、MyBatis 等)。
  5. MVC 框架支持:通过 Spring MVC 提供 Web 开发支持。

Spring中的常用注解

  1. @Component(任何层) @Controller @Service @Repository(dao): 用于实例化对象
  2. @Scope : 设置Spring 对象的作用域
  3. @PostConstruct @PreDestroy : 用于设置Spring 创建对象在对象创建之后和销毁之前要执行的方法
  4. @Value: 简单属性的依赖注入
  5. @Autowired: 对象属性的依赖注入
  6. @Resource 按照属性名称依赖注入
  7. @ComponentScan: 组件扫描
  8. @Bean: 表在方法上,用于将方法的返回值对象放入容器
  9. @PropertySource: 用于引入其它的properties 配置文件
  10. @Import: 在一个配置类中导入其它配置类的内容
  11. @Configuration: 被此注解标注的类,会被Spring 认为是配置类。Spring 在启动的时候会自动扫描并加载所有配置类,然后将配置类中bean 放入容器
  12. @Transactional 此注解可以标在类上,也可以表在方法上,表示当前类中的方法具有事务管理功能。

Spring 的两大核心是什么?谈一谈你对IOC 的理解?谈一谈你对AOP 的理解?

IOC

  • IOC 的意思是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring 容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。最直观的表达就是,IOC 让对象的创建不用去new 了,可以由spring 根据我们提供的配置文件自动生产,我们需要对象的时候,直接从Spring 容器中获取即可.Spring 的配置文件中配置了类的字节码位置及信息, 容器生成的时候加载配置文件识别字节码信息, 通过反射创建类的对象.
  • Spring 的IOC 有三种注入方式:构造器注入, setter 方法注入, 根据注解注入。

AOP

  • AOP,一般称为面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect). SpringAOP 使用的动态代理,所谓的动态代理就是说AOP 框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP 对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
  • Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和CGLIB 动态代理:
    1. JDK 动态代理只提供接口代理,不支持类代理,核心InvocationHandler 接口和Proxy 类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起,Proxy 利用InvocationHandler 动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
    2. 如果代理类没有实现InvocationHandler 接口,那么Spring AOP 会选择使用CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB 做动态代理的。

Spring框架中的设计模式?

  1. 工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例
  2. 单例模式:Bean 默认为单例模式
  3. 代理模式:Spring 的AOP 功能用到了JDK 的动态代理和CGLIB 字节码生成技术
  4. 模板方法: 用来解决代码重复的问题。比如. RestTemplate, JmsTemplate
  5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新, 如Spring 中listener 的实现--ApplicationListener

SpringBean的生命周期?

阶段
1Bean的实例化阶段
2Bean的设置属性阶段
3Bean的初始化阶段
4Bean的销毁阶段
image

Spring事务的实现方式和实现原理?

Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog 或者redo log 实现的。
spring 事务实现主要有两种方法
1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法

点击查看代码
@SpringBootApplication
public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }

@Service
public class UserService {

    private final JdbcTemplate jdbc;
    private final TransactionTemplate tx;

    public UserService(JdbcTemplate jdbc, PlatformTransactionManager txm) {
        this.jdbc = jdbc;
        this.tx = new TransactionTemplate(txm);
        // 可在这里统一设置隔离级别、传播行为
        tx.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    }

    /**
     * 转账:from -> to 转 amount 元
     * 故意在第二次 update 后制造异常,观察回滚
     */
    public void transfer(Long from, Long to, BigDecimal amount) {
        tx.execute(status -> {
            // 1. 扣钱
            if (jdbc.update("update account set money = money - ? where id = ?", amount, from) == 0)
                throw new RuntimeException("扣款账户不存在");
            // 2. 加钱
            if (jdbc.update("update account set money = money + ? where id = ?", amount, to) == 0)
                throw new RuntimeException("收款账户不存在");
            // 3. 模拟业务异常
            if (amount.compareTo(BigDecimal.ZERO) < 0)
                throw new IllegalArgumentException("金额非法");
            return null;        // 正常执行完自动 commit;抛异常则 rollback
        });
    }
}
2、声明式,利用注解Transactional 或者aop 配置
点击查看代码
@Service
public class UserService2 {

    private final JdbcTemplate jdbc;
    public UserService2(JdbcTemplate jdbc) { this.jdbc = jdbc; }

    /**
     * 同场景,代码量锐减:事务开启、提交、回滚全由 Spring AOP 完成
     */
    @Transactional(rollbackFor = Exception.class)   // 任何 Runtime/Checked 异常都回滚
    public void transfer(Long from, Long to, BigDecimal amount) {
        jdbc.update("update account set money = money - ? where id = ?", amount, from);
        jdbc.update("update account set money = money + ? where id = ?", amount, to);
        if (amount.compareTo(BigDecimal.ZERO) < 0)
            throw new IllegalArgumentException("金额非法");
    }
}
对比小结
维度 编程式 声明式
代码侵入 高,业务里夹杂 tx 模板 零侵入,注解即可
灵活度 高,可在循环里细粒度控制事务边界 一般,方法级一刀切
可读性 差,事务逻辑与业务交织 好,一眼看出事务范围
适用场景 需要复杂分支、循环、嵌套事务 90% 业务场景

实际项目:简单 CRUD → 直接 @Transactional;
需要 for 循环里每 1000 条 commit 一次 → 用 TransactionTemplate。

Spring如何解决循环依赖的?

Spring通过三级缓存解决了循环依赖,其中一级缓存为单例池( singletonObjects ),二级缓存为早期曝光对象 earlySingletonObjects ,三级缓存为早期曝光对象工厂( singletonFactories )。

posted on 2025-12-12 14:15  lubingliang  阅读(0)  评论(0)    收藏  举报

导航