关于Spring AOP(一)

来源:互联网 发布:mac哪个适合唇色深的 编辑:程序博客网 时间:2024/06/05 10:15

Spring AOP

1、什么是String AOP?

    AOP(Ascept Oriented Programming)    1)Spring框架核心功能之一    2)Spring中的面向切面编程(区分oop)    3)Spring中业务对象的横切面

2、String AOP特点?

    1)在不改变原始代码的基础上拓展新的功能业务    2)可以简化代码开发,提高效率

3、String AOP应用场景

    1)系统日志处理    2)系统事务处理    3)系统安全验证    4)系统数据缓存

4、String AOP核心概念和术语

    AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。其相关概念术语如下:    切面(aspect): 横切面对象,一般为一个具体类对象(可以借助@Aspect声明);    连接点(joinpoint):程序执行过程中某个特定的点,一般指被拦截到的的方法;    切入点(pointcut):对连接点拦截内容的一种定义;    通知(advice):拦截到连接点之后只要执行的方法;    目标对象(target):代理的目标对象;    通知(Advice):在切面的某个特定连接点上执行的动作,例如before,after等; 知识点术语强化:   1)切面(可以简单理解为要植入的新的业务功能,这个功能交给某个负责,这个类就是切面)  2)通知(可以简单理解为一个业务中的若干步骤,例如先做什么(before),再做什么(afterReturn),最后做什么) 3)切入点(在原有的哪些业务方法上扩展新的业务,可以将切入点理解为方法的集合)4)连接点(可以简单理解为切入点中的一个具体方法)5)目标对象(需要扩展功能的那个对象,一般为被代理对象)6)代理对象(负责调用切面中的方法为目标对象植入新的功能) 

5、String AOP底层通过动态代理实现

  /**代理对象的处理对象,此类不是代理对象*/public class ProxyHandler          implements InvocationHandler{    /**代表目标对象(要此对象产生代理对象)*/    private Object target;    /**     * @param  target目标对象(后续要为此对象产生代理对象)     * @return 返回目标对象的代理对象     * */    public Object newProxy(Object target){        this.target=target;        //为目标对象创建代理对象(这个过程是动态的)        //底层创建的这个代理对象也会与被代理对象实现相同的接口        return Proxy.newProxyInstance(//class A{} A.class                target.getClass().getClassLoader(),//loader目标类的加载器                target.getClass().getInterfaces(),//interfaces目标类实现的接口                this);//InvocationHandler    }    /**在执行目标对象方法时,会默认调用此方法     * @param proxy 代理对象     * @param method 代表方法对象(通过此对象执行目标方法)     * @param args 用于接收目标方法中实际参数的值     * */    public Object invoke(Object proxy,            Method method,             Object[] args) throws Throwable {        long t1=System.currentTimeMillis();        //这句话的含义是要执行目标对象(target)的method        //例如执行TeamServiceImpl对象的saveObject方法        Object result=            method.invoke(target, args);        long t2=System.currentTimeMillis();        System.out.println(method.getName()                +"方法执行时间:"+(t2-t1));        return result;    }

测试类

public static void main(String[] args) {        //目标对象        TeamService tService=        new TeamServiceImpl();        Object obj=new Object();        //tService.saveObject(obj);        //tService.updateObject(obj);        //==================        //创建代理对象(为TeamServiceImpl创建代理)        ProxyHandler pHandler=        new ProxyHandler();        TeamService proxyObject=        (TeamService)pHandler.newProxy(tService);        //1)调用代理对象的方法        //2)底层调用pHandler的invoke方法        //3)invoke方法执行调用目标对象对应的方法        proxyObject.saveObject(obj);        proxyObject.updateObject(obj);        //创建代理对象(为ProjectServiceImpl创建代理)        ProjectService pService=        new ProjectServiceImpl();        ProjectService pServiceProxy=(ProjectService)        pHandler.newProxy(pService);        pServiceProxy.saveObject(obj);        pServiceProxy.updateObject(obj);    }

6、Spring AOP 用注解来实现

1)配置文件
    <!-- 自动扫描该包     @Controller    @Service    ....    -->    <context:component-scan      base-package="com.tong" />    <!-- 使aspectj注解生效,         自动为目标对象生成代理对象 -->    <aop:aspectj-autoproxy/>
2)添加依赖
<dependencies>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context</artifactId>            <version>4.3.9.RELEASE</version>        </dependency>        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjrt</artifactId>            <version>1.8.9</version>        </dependency>        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjweaver</artifactId>            <version>1.8.9</version>        </dependency>        <dependency>            <groupId>Junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>        </dependency>    </dependencies>
3)切面代码
@Aspect@Componentpublic class TimingAspect {    long start;    @Before("bean(*ServiceImpl)")    public void testBefore(){        start = System.currentTimeMillis();        System.out.println("start.time="+start);    }    @After("bean(*ServiceImpl)")    public void testAfterReturn(){        System.out.println("After");    }    @AfterThrowing("bean(*ServiceImpl)")    public void testAfterThrow(){        System.out.println("出现异常");    }    @AfterReturning("bean(*ServiceImpl)")    public void testAfter(){        long end = System.currentTimeMillis();        long time = end-start;        System.out.println("end.time="+end);        System.out.println("耗时"+time);    }
通知说明:通知说明:@Before: 前置通知,切面方法在目标方法之前执行@After: 后置通知,切面方法在目标方法之后执行@AfterReturning:返回通知 切面方法在目标方法正常结束之后执行@AfterThrowing: 异常通知,切面方法在目标方法异常之后执行@Around:环绕通知, 可以在业务方法前后调用