spring创建对象的作用域
springBean有五个作用域:
singleton:(单例)作用域为ApplicationContext中
prototype:每次注入都会生成一个新的实例,作用域返回的getBean方法直至方法结束
request:每次http请求都会创建一个新的Bean,作用域是每次发起请求直至拿到相应的结果,
该作用域只适用于WebApplicaionContext。
session:每次会话创建一个实例,作用域是浏览器首次访问直至浏览器结束。同一个http中Session是共享的,不同的Session使用不同的Bean,仅适用于WebApplicationContext环境。
global-session:作用域WebApplicaionContext,一般用于Portlet应用环境
Spring中Bean的生命周期
单例对象的生命周期:容器启动,单例对象创建,容器关闭,单例对象被销毁。
两种方式修改作用域:
<bean id="userController" class="com.example.UserController" scope="session"/>
@RestController
@Scope("session")
public class UserController {
private int flag = 0;
@RequestMapping("/getUser")
public int getUser(){
return flag++;
}
}
单例创建的线程安全问题
解决思路:设置为多例模式(@scope(prototype))还可以使用TheardLocal
Spring底层有些方法的创建是单例模式,底层使用ThreadLocal进行处理的(RequestContextHolder)
ThreadLocal实现思路:它为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,因为每个线程都有自己的变量副本,从而没有必要对该变量进行同步了。
IOC创建的三种方式
构造方法:将要交给ioc容器创建的类加上构造方法。
普通工厂创建对象:自定义工厂使用方法进行创建
<bean id="instanceFactory" class="com.sks.util.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
普通工厂的静态方法创建对象:
<bean id="accountService" class="com.sks.util.staticFactory" factory-method="getAccountService"></bean>
注:普通工厂的普通方法创建于工厂的静态方法创建的方式不同之处:便是工厂不需要new对象,直接调用即可。
IOC
IOC(控制反转):是一种设计思想,是将设计好的对象交给容器控制,反转便是将容器帮忙创建和注入依赖对象,依赖对象的获取反转了。
作用:对象和对象之间的松耦合,也有利于功能的复用。
DI(依赖注入):di更加准确的描述了ioc的设计理念,所谓依赖注入就是i将服务注入到使用它们的地方。
AOP
使用原因:对于一些方法,抽取它们的非核心方法提取出来编写成一个切面类,切面类可以在使用加减乘除的时候加一个日志功能,那么日志功能就是非核心业务。
AOP(面向切面):
AspectJ 支持 5 种类型的通知注解:
@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行
@AfterRunning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around: 环绕通知, 围绕着方法执行
使用地方:表示标有@java.lang.Deprecated注解的所有方法
AOP的代理方式:
JDK和CGLib
JDK动态代理是面向接口的代理模式,如果代理目标没有接口那么Spring也没有办法,Spring通过java的反射机制被代理接口的新的匿名实现类,重写了其中AOP的增强方法。
CGLib是一个强大,高性能的Code生产类库,可以实现运行期间动态扩展java类。
两者对比:
JDK动态代理是面向接口的
CGLIB动态代理是通过字节码底层继承要代理类来实现(如果代理类被final关键字修饰,则会是失败),
CGLib在创建的动态代理对象在实际运行的时候的性能要比JDK动态代理高上不少。
JDK在创建对象时花费的时间比CGLib快上不少
因此,对于单例的代理对象或者有实例池的代理,无需频繁的创建代理对象则使用CGLib
反之JDK
IOC注入的三种方式
接口注入
set方法注入
构造器注入
注:二三种为常见