架构师之路--AOP理解

概念
AOP面相切面编程 是一种编程范式。

初衷
1.don’t repeat (减少重复代码 例 切面日志)
2.separation of concerns (关注点分离 水平 垂直 切面分离 例 具体业务点)

应用场景
场景一: 记录日志 审计日志
场景二: 监控方法运行时间 (性能监控)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
场景六:分布式追踪
场景七:异常处理

应用解析
@Transactional事务service层控制
@PreAuthorize安全
@Cacheable缓存

切面通知
前置通知:@Before 在目标业务方法执行之前执行
后置通知:@After 在目标业务方法执行之后执行
返回通知:@AfterReturning 在目标业务方法返回结果之后执行
异常通知:@AfterThrowing 在目标业务方法抛出异常之后
环绕通知:@Around 功能强大,可代替以上四种通知,还可以控制目标业务方法是否执行以及何时执行

原理解析
代理模式
责任链模式

静态代理
动态代理

动态代理实现原理
JDK动态代理
适合interface

@Test
public void test() {

    final User user = new UserImpl();
    // newProxyInstance的三个参数解释:
    // 参数1:代理类的类加载器,同目标类的类加载器
    // 参数2:代理类要实现的接口列表,同目标类实现的接口列表
    // 参数3:回调,是一个InvocationHandler接口的实现对象,当调用代理对象的方法时,执行的是回调中的invoke方法
    //proxy为代理对象
    User proxy = (User) Proxy.newProxyInstance(user.getClass().getClassLoader(),
            user.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                // 参数proxy:被代理的对象
                // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法
                // 参数args:执行方法的参数
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("saveUser之前的操作");
                    Object result = method.invoke(user, args);
                    return result;
                }
            });
    //代理对象执行方法
    proxy.saveUser();
}

Cglib动态代理
适合Superclass

@Test
public void test() {
    final User user = new UserImpl();
    // 创建cglib核心对象
    UserSon userSon = new UserSon();
    // 设置父类
    userSon.setSuperclass(User.getClass());
    // 设置回调
    userSon.setCallback(new MethodInterceptor() {
        /**
         * 当你调用目标方法时,实质上是调用该方法
         * intercept四个参数:
         * proxy:代理对象
         * method:目标方法
         * args:目标方法的形参
         * methodProxy:代理方法
        */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
                throws Throwable {
            System.out.println("saveUser之前的操作");
             Object result = method.invoke(User, args);
            return result;
        }
    });
    // 创建代理对象
    User proxy = (User) userSon.create();
    proxy.saveUser();
}

AOP切面中启用新事务

@Autowired
private TransactionTemplate transactionTemplate;

@AfterReturning(returning = "ret", pointcut = "remote()")
public void doAfterReturning(JoinPoint joinPoint,Object ret) throws Throwable {
    //声明式事务在切面中不起作用,需使用编程式事务
    //设置传播行为:总是新启一个事务,如果存在原事务,就挂起原事务
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    transactionTemplate.execute(new TransactionCallback<T>() {
        @Override
        public T doInTransaction(TransactionStatus arg0) {
            //一些切面逻辑,包含了数据库操作
        }   
    });
}

随笔
jdk
Cglib
织入时期
编译期aspectj
类加载期aspectj 5+
运行时spring aop
怎么实现?代理对象 ,静态和动态代理
静态,代理对象实现接口,并调用实体方法本身
动态,
接口,invocationhandler  增加result args
Client调用时,注意。newproxyinstance
Jdk只能接口 无private
和继承代理Cglib 不能static final private
接口使用jdk代理,其他使用cglib代理。
SpringAOP  proxyTargetClass为true强制使用cglib代理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值