SpringAop 原理

著名的spring两大杀手锏:IOC 和 AOP,今天来说下AOP。

缘起:

    AOP:面向切面编程,是独立于spring的。spring Aop是AOP的实现框架
    之一。

Spring Aop

    Spring Aop是用动态代理机制实现的。先简单说下动态代理(大家都知道
    代理有两种方式:静态代理和动态代理),动态代理(JDK实现方式)涉
    及的四个概念:目标对象、代理对象、InvocatoinHandler接口、Proxy类。
    直接上代码:
处理器类:
public class MyInvocationHandler implements InvocationHandler{

    //目标对象
    private Object target;

    private IUserServiceManager userServiceManager;

    public MyInvocationHandler(Object target,IUserServiceManager userServiceManager){
        this.target = target;
        this.userServiceManager = userServiceManager;
    }

    /**
     * 调用
     * @param proxy 代理对象
     * @param method 目标方法
     * @param args 目标方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //非核心代码
        userServiceManager.before();
        //核心业务代码
        Object result = method.invoke(target,args);
        //非核心代码
        userServiceManager.after();
        return result;
    }
}

增强类接口:
public interface IUserServiceManager {

    public void before();

    public void after();
}
增强类实现:
public class UserServiceManagerImpl implements IUserServiceManager{

    private ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();

    @Override
    public void before() {
        long nowTimeSeconds= System.currentTimeMillis();
        threadLocal.set(nowTimeSeconds);
        System.out.println("UserServiceManagerImpl before-->time:"+
                nowTimeSeconds);
    }

    @Override
    public void after() {
        long nowTimeSeconds2= System.currentTimeMillis();
        System.out.println("UserServiceManagerImpl after-->time:"+
                nowTimeSeconds2);
        System.out.println("UserServiceManagerImpl 方法耗时:"+
                (threadLocal.get()-nowTimeSeconds2));
    }
}
目标类:
public class UserServiceImpl implements IUserService{
    @Override
    public void add() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("UserServiceImpl add...");
    }
}

测试类:
@RunWith(SpringRunner.class)
@ContextConfiguration
public class JDKProxyTest {

    @Test
    public void jdkProxyTest(){

        //生成一个目标对象
        IUserService target = new UserServiceImpl();

        //增强对象
        IUserServiceManager userServiceManager = new UserServiceManagerImpl();

        //生成一个handler
        MyInvocationHandler handler = new MyInvocationHandler(target,userServiceManager);
        //使用JDK生成代理对象
        IUserService userService = (IUserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);
        //代理对象执行目标方法
        userService.add();

    }

    @Test
    public void springAopTest(){
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AopProxyConfig.class);
//          第二种方式ctx
//        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
//        ctx.register(AopProxyConfig.class);
//        ctx.refresh();
        IUserService userService = (IUserService) ctx.getBean("userServiceImpl");
        userService.add();
    }
}

    上面将采用Spring Aop后,handler就不用我们自己写了,Spring已经写好了,咱们直接用就行了,
    但是需要按照spring提供的规则使用的。只需要定义增强类(切面)就可以了。其他怎么组织是Spring的事情了,但前提是所有的bean都先
    归spring进行管理(可以通过打开注解扫描或者使用全注解方式)。代码如下(注意注解):
    `
    (增强类)切面类:
 @Aspect
 @Component

public class MyAspect {

@Before("execution(public * mianshi.Proxy.service.*.*(..))")
public void hi(){
    System.out.println("切面编程--前置");
}

@After("execution(public * mianshi.Proxy.service.*.*(..))")
public void hi2(){
    System.out.println("切面编程--后置");
}

}`

就是这么简单搞定。spring框架还不错。。
测试一下:

@Test
public void springAopTest(){

    ApplicationContext ctx = new AnnotationConfigApplicationContext(AopProxyConfig.class);

// 第二种方式ctx
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// ctx.register(AopProxyConfig.class);
// ctx.refresh();
IUserService userService = (IUserService) ctx.getBean("userServiceImpl");
userService.add();

}

总结:spring ioc利用动态代理的机制实现了面向切面编程。使用场景最多的就是事务和日志处理、监控等。

文章写得有不明白之处,请留言……

转载于:https://blog.51cto.com/jiaxiaoxu/2369646

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值