spring源码手写aop

 

AOP:

      aop切面编程,其实就是spring增强器的一个扩展,就是通过beanPostProcessor的after后置方式实现的,其中在after中把需要的bean通过放射+动态代理完成bean的替换,替换成代理bean。然后通过注册拦截器完成代理方式的执行;

    1、代理对象的创建过程(advice,切面、切点)

    2、通过jdkcglib的方式生产代理对象(通过beanPostProcessor的after后置方式实现)

    3、执行方法回调的时候,会到字节码的文件中,直接找回到DynamicAdviceedInterceptor中的intercept方法,在这里执行

              4、在执行过程中,会生成之前定义好的通知拦截器,来执行

    Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

    

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。

  JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。

  CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

 

1、首先要注入 @EnableAspectJAutoProxy

@EnableAspectJAutoProxy
@ComponentScan(value = "com.flm")
public class Config {
}

2、创建service

@Component
public class UserServiceImpl implements UserService {
    public UserServiceImpl(){
        System.out.println("UserServiceImpl 构造方法 create ......");
    }
@PostConstruct
private void rn(){ System.out.println("UserServiceImpl 使用@PostConstruct run... ......"); } @Override public String test(){ System.out.println("aop test 业务逻辑...."); return "OK"; } @Override public void testData() { System.out.println("testData 业务逻辑...."); } }

 

3、启动类

public class APP {
    public static void main(String[] args) {
        //  方式1:指定xml启动
//         ApplicationContext context = new ClassPathXmlApplicationContext("beans-context-content.xml");
        // 方式二:指定配置类启动
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (Config.class);

        // 在spring容器获取bean
        UserService userService = context.getBean(UserService.class);
        // 执行要aop的接口
        String rt = userService.test();
        System.out.println(rt);
        userService.testData();
    }
}

 

4、自定义aop方法(原理)

@Component
public class AopPostProcessor implements BeanPostProcessor {
    // 原理 BeanPostProcessor + jdk动态代理实现
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 判断哪个接口需要代理的 ,写死
        if("userServiceImpl".equals(beanName)){
            // 创建代理对象 , JDK代理是依赖接口的,有实现接口的为jdk代理,否则为 cglib代理
            Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(), UserServiceImpl.class.getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object result = null;
                    // 判断哪个方法需要代理使用执行的,现在写死test
                    if("test".equals(method.getName())){
                        // 方法之前执行
                        System.out.println("invoke before ...");
                        // 执行方法
                        result = method.invoke(bean, args);
                        // 方法之后执行
                        System.out.println("invoke after ...:"+result.toString());
                    }
                    // 执行方法 返回结果
                    return result;
                }
            });
            return proxyInstance;
        }
        return bean;
    }
}

 

最后执行userSerie.test(),aop拦截结果如下

 

 

 

 

================

详情源码看这个大神写的

https://www.cnblogs.com/liuyk-code/p/9886033.html

 

posted @ 2021-09-30 17:00  低调人生  阅读(122)  评论(0编辑  收藏  举报