标签:ring 怎么 线程安全 一个 直接 动态代理 范围 ssl rri
Spring IOC框架,控制反转,依赖注入
以前是xml文件来进行一个配置,后面进化到了基于注解来进行自动依赖注入
Spring ioc,spring 容器,根据xml配置,或者是你的注解,去实例化你的一些bean对象,然后根据xml配置或者注解,去对bean对象之间的应用关系,去进行依赖注入,某个bean依赖了另外一个bean
底层的核心技术,反射,它会通过反射的技术,直接根据你的类去自己构建对应的对象出来,用的就是反射的技术
ps:自由发挥
比如说我们平时有两个类,MyserviceA和MyserviceB,在类里面有他自己的方法,doServiceA和doServiceB,在方法里面我们会进行增删改查的操作,一般进行这种操作我们都会考虑到事务,所以我们会加入开启事务,回滚事务,提交事务,关闭事务的代码。通过AOP,我们做一个切面,比如MyserviceXXXX的这种类,在这些类的所有方法中,都去织入一些代码,在所有这些方法刚开始运行的时候,都会先去开启一个事务,在所有这些方法运行完毕后,去根据是否抛出异常来判断事务的具体操作
AOP的核心技术就是动态代理
ps:看下手写代理模式的代码。
优先jdk动态代理,其次是cglib动态代理
动态代理其实就是动态的创建一个代理类出来,创建这个代理类的实例对象,在这个里面引用你真正自己写的类,所有的方法的调用,都是先走代理类的对象,它负责做一些代码上的增强,再去调用你自己写的那个类
如果你的类是实现了某个接口的,spring aop 会使用jdk动态代理,生成一个跟你实现同样接口的一个代理类,构造一个实例对象出来,jdk动态代理,它其实是在你的类有接口的时候,就会来使用
很多时候我们可能某个类是没有实现接口的,spring aop会改用cglib来生成动态代理,他是生成你的类的一个子类,它可以动态生成字节码,覆盖你的一些方法,在方法里加入增强的代码
public class CglibMeipo implements MethodInterceptor { public Object getInstance(Class<?> clazz) throws Exception { Enhancer enhancer = new Enhancer(); //要把clazz设置为即将生成的新类父类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("我是媒婆:我要给你找对象,已经拿到你的需求"); System.out.println("开始物色"); methodProxy.invokeSuper(o,objects); System.out.println("如果合适的话,准备办事"); return null; } }
public class JdkMeipo implements InvocationHandler { //把被代理的对象保存下来 private Person target; public Object getInstance(Person target) throws Exception{ this.target = target; // Class clazz = Class.forName(this.target.getClass().getName()); Class clazz = target.getClass(); return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this); //loader:Proxy.newProxyInstance的三个参数分别代表什么 //interfaces:用哪个类加载器去加载类对象 //h:动态代理方法执行时,会调用h里面的invoke方法去执行 } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是媒婆:我要给你找对象,现在已经拿到你的需求"); System.out.println("开始物色"); method.invoke(this.target,args); System.out.println("如果合适的话,就准备办事"); return null; } }
spring容器中的bean可以分为5个范围:
(1)singleton:默认,每个容器中只有一个bean的实例
(2)prototype:为每一个bean请求提供一个实例
一般来说下面三种作用域一般不会用
(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收
(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效
(5)global-session
那么是不是线程安全的了?答案是否定的,比如说在某个类有个int data = 0变量,类里面有个方法进行data++操作,当多个线程去请求bean就会发生线程不安全,怎么解决,就是不要去访问内存中的共享数据,而是去访问数据库。
标签:ring 怎么 线程安全 一个 直接 动态代理 范围 ssl rri
原文地址:https://www.cnblogs.com/zhangliang1726/p/12187558.html