栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

AOP底层实现原理、基于注解的AOP编程、AOP开发中的一个坑 打卡第八天

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AOP底层实现原理、基于注解的AOP编程、AOP开发中的一个坑 打卡第八天

第五章、AOP底层实现原理 1. 核心问题

1.AOP如何创建动态代理类(动态字节码技术)

2.Spring工厂如何加工创建代理对象

通过原始对象的id,获得的是代理对象

2. 动态代理的创建 2.1JDK的动态代理 (原理 + 编码)

1.Proxy.newProxyInstance方法参数详解

2.编码

public class TestJDKProxy {
   
    public static void main(String[] args) {
        //1.创建原始对象
        UserServiceImpl userService = new UserServiceImpl();
        //2.JDK创建动态代理
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("---------proxy log----------");
                //原始方法运行
                Object ret = method.invoke(userService, args);
                return ret;
            }
        };
        UserService userServiceProxy =(UserService) Proxy.newProxyInstance(TestJDKProxy.class.getClassLoader(), userService.getClass().getInterfaces(), handler);
        userServiceProxy.register(new User());
        userServiceProxy.login("liulei","123456");
    }
}

2.2 CGlib的动态代理

CGlib创建动态代理的原理:父子继承关系创建对象,父类为原始类,子类为代理类,这样既可以保证二者方法一致,同时能够在代理类中提供新的实现(额外功能+原始方法)

CGlib编码

public class TestCGlib {
    public static void main(String[] args) {
        //1.创建原始对象
        UserService userService = new UserService();
        //2.通过CGlib的方式创建动态代理对象
        //对比JDK:Proxy.newProxyInstance(classloader,interfaces,invocationhandler)
       
        Enhancer enhancer = new Enhancer();
        enhancer.setClassLoader(TestCGlib.class.getClassLoader());
        enhancer.setSuperclass(userService.getClass());
        MethodInterceptor interceptor = new MethodInterceptor() {
            //等同InvocationHandler----invoke
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("-----log------");
                Object ret = method.invoke(userService, args);
                return ret;
            }
        };
        enhancer.setCallback(interceptor);
        UserService userServiceProxy = (UserService)enhancer.create();
        userServiceProxy.login("liulei","13245");
        userServiceProxy.register(new User());
    }
}

总结

1.JDK动态代理 Proxy。newProxyInstance() 通过接口创建代理的实现类

2.Cglib动态代理 Enhancer 通过继承父类创建代理的实现类

3.Spring工厂如何加工原始对象

思路分析

编码

public class ProxyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Override
   
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("---------log--------");
                Object ret= method.invoke(bean, args);
                return ret;
            }
        };
        return Proxy.newProxyInstance(ProxyBeanPostProcessor.class.getClassLoader(),bean.getClass().getInterfaces(),handler);
    }
}

配置文件




第六章、基于注解的AOP编程 1.基于注解的AOP编程的开发步骤

1.原始对象

public interface UserService {
    void register(User user);
    boolean login(String name,String password);
}


public class UserServiceImpl implements UserService {
    
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");
        // throw new RuntimeException("测试异常");
    }

    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login");
        return true;
    }
}

2.额外功能

3.切入点

4.组装切面

#通过切面类定义了 额外功能 @Around

切入点 @Around(* login(..))

@Aspect 切面类

2.3.4都放在MyAspect类中完成

@Aspect

public class MyAspect {
    @Around("execution(* login(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("-------------log-----------");
        Object ret = joinPoint.proceed();
        return ret;
    }
}

配置文件








2.细节

切入点复用:在切面类中定义一个函数,上面@Pointcut注解 通过这样的方式,定义切入点表达式,有利于切入点的复用

@Aspect
public class MyAspect {
    
    @Pointcut("execution(* login(..))")
    public void myPointcut(){}
    
    @Around(value = "myPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("-------------log-----------");
        Object ret = joinPoint.proceed();
        return ret;
    }

    @Around(value = "myPointcut()")
    public Object around1(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("-------------logty-----------");
        Object ret = joinPoint.proceed();
        return ret;
    }
}

2.动态代理对象的创建

AOP底层实现 2种代理创建方式

1.JDK 通过实现接口 做新的实现类方式 创建代理对象

2.Cglib 通过继承父类 做新的子类 创建代理对象

默认:AOP编程 底层应用JDK动态代理创建方式

如果切换Cglib

1.基于注解AOP开发

2.传统的AOP开发


    ...

第七章、AOP开发中的一个坑

坑:在同一个业务类中,进行业务方法间的相互调用,只有最外层的方法,才是加入额外功能(内部的方法,通过普通的方式调用,调用的都是原始方法),如果想让内层的方法也调用代理对象的方法的,ApplicationContextAware获得工厂,进而获得代理对象

public class UserServiceImpl implements UserService, ApplicationContextAware {
   private ApplicationContext ctx;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }
    @Log
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");
        // throw new RuntimeException("测试异常");
        //this.login("liulei","123465");
       
        UserService userService = (UserService)ctx.getBean("userService");
        userService.login("liulei","123456");
    }
    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login");
        return true;
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1036910.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号