面试十一、spring的AOP和IOC,底层原理

参考链接:https://blog.csdn.net/liyifan687/article/details/90678729

 

1、AOP

  1.1、面向切面编程,可分为静态代理和动态代理

  1.2、3个实现

    AspectJ:静态代理,我们在编写一段独立业务代码时可以使用aspectj将逻辑加入

          业务方法中(比如常用的操作日志记录),在编译后我们的class文件会

          多出一段代码,这段代码就是aspectj在编译时增加的aop代码。这种做法可以称为静态代理

           代理类在调用被代理类方法前后增加一些切面逻辑。

 

 

    JDK动态代理:使用jdk的反射机制来完成aop的动态代理,有如下要求:

            1)被代理类(我们实现业务的类)要实现统一接口

            2)代理类要实现reflect包里面的InvacationHandler

            3)通过jdk proxy提供的静态方法newProxyInstance(xxx)来动态创建代理类

              注:proxy是jdk动态生成的代理类,和service属于同一个类,

                但是save方法被动用时jdk为我们自动的实现类切面逻辑。

           使用jdk反射机制,生成一个继承Proxy的代理类。实现了InvocationHandler接口,

           在调用方法时实际会先经过invoke方法转发,所以可以在invoke方法上增加一些切面逻辑

 

 

 1 // 统一接口
 2 public interface IService {
 3     void save();
 4 }
 5 
 6 // 接口实现类
 7 public class UserService implements IService{
 8     @Override
 9     public void save() {
10         System.out.println("save a user ...");
11     }
12 }
13 
14 // 实现InvacationHandler
15 public class MyHandler implements InvocationHandler {
16     private Object target;
17 
18     MyHandler(Object target) {
19         this.target = target;
20     }
21     //在这里实现我们的切面逻辑
22     @Override
23     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
24         System.out.println("before ...");
25         Object result = method.invoke(target, args);
26         System.out.println("after ...");
27         return result;
28     }
29 }
30 
31 // 客户端代码
32     public static void main(String[] args) {
33         //创建被代理类
34         IService service = new UserService();
35         //新建代理类,将被代理类注册到里面
36         MyHandler aop = new MyHandler(service);
37         //Proxy为MyHandler动态创建一个符合某一接口的代理实例
38                 //第一个参数:获取被代理类的class loader
39                 //第二个参数:获取被代理类实现的接口, 由此可见被代理类需要实现统一的接口
40                 //第三个参数:InvocationHandler的实例, 也就是我们做切面逻辑的类
41         IService proxy = (IService) Proxy
42                 .newProxyInstance(service.getClass().getClassLoader(),
43                         service.getClass().getInterfaces(),
44                         aop);
45                 //调用代理方法
46         proxy.save();
47     }
48 
49 // 输出结果
50 before
51 save user
52 after

    GGLIB:全称Code Generation LIbrary,代码生产库。

        基于字节码技术,修改被代理类的.class文件生成代理类的子类,并重写了代理类的方法。

        实现了MethodInterceptor接口,在interceptor方法里增加切面逻辑

 

 

 1 // 定义被代理类
 2 public class UserService{
 3     public void save() {
 4         System.out.println("save a user ...");
 5     }
 6 }
 7 
 8 // 实现MethodInterceptor接口(切面逻辑)
 9 public class UserProxy implements MethodInterceptor {
10     @Override
11     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
12         //方法执行前的逻辑
13         System.out.println("before ...");
14         e
15         Object result = methodProxy.invokeSuper(o, objects);
16         //方法执行后的逻辑
17         System.out.println("after ...");
18         return result;
19     }
20 }
21 
22 // 获取被代理类工厂,该工厂专门生产加入了切面的被代理类
23 public class UserServiceFactory {
24     public static UserService getInstance(UserProxy proxy) {
25         Enhancer enhancer = new Enhancer();
26         enhancer.setSuperclass(UserService.class);
27         //设置回调类,强化类调用回调类中的intercept方法来执行我们定义好的切面逻辑
28         enhancer.setCallback(proxy);
29         //返回一个添加了切面逻辑的增强类
30         return (UserService) enhancer.create();
31     }
32 }
33 
34 // 客户端调用
35     public static void main(String[] args) {
36         UserProxy proxy=new UserProxy();
37         //通过工厂方法模式获取增强类
38         UserService service = UserServiceFactory.getInstance(proxy);
39         service.save();
40     }

  1.3、jdk动态代理和CGLIB区别

    CGLIB是通过字节码技术,在程序运行时为类创建了一个子类,重写了父类的方法

      并加入了切面逻辑(无法代理final方法)。

      优点:继承原对象并重写方法,所有能代理普通类。

    jdk动态代理是运用jdk反射机制,根据代理类和代理接口生成新的字节码,然后进行加载并生成

      对象。

      优点:生成代理类相对较快,

      缺点:但是运行切面逻辑没有CGLIB快,且要实现统一接口扩展性较差。因为要继承Proxy类

        所以只能代理接口类。

2、IOC

  2.1、控制反转(获得依赖对象的方式被反转)

    在业务中一般都需要至少两个对象来完成,那么通常情况下每个对象在使用时都需要new,

      这样就导致对象之间的耦合度高了。IOC的思想就是Spring容器来实现这些相互依赖

    对象的创建、协调,对象只需要关心业务逻辑本身就行了。

    底层原理:反射技术

posted on 2021-08-26 23:02  Iversonstear  阅读(2286)  评论(0编辑  收藏  举报

导航