自学内容网 自学内容网

Spring框架

Spring Framework,它是很多模块的集合。比如IOC、AOP、一些第三方组件,同时支持JUnit单元测试框架。

核心思想:不用我们开发者造轮子,开箱即用,提高开发效率。

IOC依赖注入:Spring其他所有功能都需要依赖该模块
IOC容器时Spring实现IOC的载体,IOC容器实际上就是个Map,存放的时各种对象。

Bean指的是那些被IOC容器所管理的对象。

@Autowired 和 @Resource区别

@Autowired是Spring内置注解,默认为byType,如果相同类型的有多个,在byName。
经常与@Qualifier注解连用,用于指定变量名称。通过value属性。
支持构造函数、方法、字段、参数。
即支持属性注入、setter注入以及构造方法注入。

@Resource是JDK内置注解,默认为byName,如果没有匹配到就byType。
当然该注解下也有name和type两个属性,可以去手动去指定变量名称和变量类型
只支持字段和方法,不支持构造函数和参数....
即支持属性注入和setter方法注入,不支持构造方法注入。

为什么不推荐用@Autowired标记字段,即属性注入?

首先我们要知道,依赖注入三种方式,即属性注入、setter方法注入、构造方法注入:
属性注入就是字段上加一个注解,这里不再赘述;
构造方法注入:

@RestController
public class UserController {
    // 构造方法注入
    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

setter方法注入:

@RestController
public class UserController {
    // Setter 注入
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

因此,属性注入的弊端显现出来:
使用@Autowired注解的代码比较难以理解和分析。对于阅读代码的开发人员来说,他们很难准确地知道这个依赖从哪里来;
不便于单元测试,依赖的实例是自动注入的,测试时很难对依赖进行模拟或替换。这会增加单元测试的复杂性。

Bean的作用域

通过@Scope注解来指定,有:
单例 【容器中只有唯一的实例】、多例 【每次获取,容器都会创建一个新的实例】、
以下只针对web应用:
request【每次Http请求】、session【同一浏览器的多次会话公用】、application【每次web应用全局】

Bean是线程安全的吗

多例Bean是线程安全的,每次获取都会创建一个新的 bean 实例,不存在资源竞争问题。
如果是单例Bean需要分情况:
如果这个Bean对象是无状态的,则它是线程安全的;如果它是有状态的,则是线程不安全的。
有状态 Bean 是指包含可变的成员变量的对象
项目中,我们一般是通过ThreadLocal成员变量,将需要的可变成员变量保存。这样能避免出现线程安全问题。

Bean的生命周期

①创建Bean的实例,即实例化;Bean 容器通过 Java 反射 API 来创建 Bean 的实例。
②进行依赖注入,属性赋值、填充;如@Autowired、@Resource、@Value、Setter或构造方法
③初始化阶段,分为初始化前和初始化后{
如果Bean实现了Aware接口,则先通过Aware的方法,让Bean能拿到Spring容器资源
如果Bean实现了BeanPostProcessor接口,执行前置处理器的方法
如果Bean实现了InitializingBean接口,则执行afterPropertiesSet方法
如果配置了init-method或者@PostConstruct,执行指定的方法
如果Bean实现了BeanPostProcessor接口,执行后置处理器方法
}
④销毁阶段,销毁并不是说要立马把 Bean 给销毁掉,而是把 Bean 的销毁方法先记录下来,将来需要销毁 Bean 或者销毁容器的时候,就调用这些方法去释放 Bean 所持有的资源。
如果Bean实现了DisposableBean接口,则执行destroy方法
如果配置了destroy-method或者@PreDestroy,执行指定的方法

 

AOP

将那些与业务无关,却为业务模块所共同调用的逻辑和责任封装起来,便于减少系统的重复代码,降低模块间的耦合,并有利于可拓展性和可维护性。
Spring AOP 包括动态代理静态【字节码操作,AspectJ AOP,Spring集成的】:

动态代理分为JDK Proxy ,用于实现了接口的对象;Cglib,用于没有实现接口的对象,生成一个代理对象的子类作为代理。


原文地址:https://blog.csdn.net/weixin_64842400/article/details/139142631

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!