springaop自动代理

来源:互联网 发布:linux下安装samba 编辑:程序博客网 时间:2024/06/05 09:40

一、背景
spring的aop就是切面编程,切面编程的意思,就是横向对方法进行拦截,加入统一的自定义处理逻辑。比如,统计所有方法的执行次数、统计所有方法的执行时间、在打印所有方法的返回值等等。
切面编程用到的就是jdk的代理,也就是设计模式中的代理模式。代理模式即对目标对象创建一个代理对象,代理对象持有目标对象的引用,因此调用代理对象,就完全可以实现对目标对象的调用,而代理对象是我们自己创建的,因此可以在不侵入到目标对象的情况下,添加自定义逻辑。

二、一些概念
1、通知
在springaop中,通知就是切面任务,即在我们对目标对象进行代理之后,需要做的事情,例如上面所说的统计方法的执行次数、打印日志等行为。

2、目标对象
这个是我们要进行切面拦截的对象,我们要对某种场景进行拦截,必须要有一个对象。有时候我们甚至不关注目标对象具体要完成的任务,例如,在统计目标对象执行的时间,我们只关注方法执行的时间就行了。

3、切点
切点标注了什么地方进行切面任务,可以是一个bean,可以是一个方法,支持正则表达式,例如以process结尾的方法等。

4、PointcutAdvisor
该对象用于将通知和切点绑定。当我们分别定义了切点和通知后,spring还不知道切点和通知的关系,因此需要一个绑定

5、自动代理
上面讲了一大堆概念,最重要的还是为目标对象产生一个自动代理,也就是我在调用目标对象的时候,如何才能执行通知。spring提供了一种非常好的自动代理的功能,可以根据PointcutAdvisor直接为目标对象生成一个代理对象,在bean factory中该bean id存放的就是该代理对象,当我们通过Cal cal = (Cal)appCtx.getBean(“computer”);
方法取出的就是代理对象。

三、代码
首先,我们要创建一个接口和实现,因为spring的jdk代理需要接口,实现当然需要,就是具体的目标对象的类。
然后就是创建一个通知,就是代理目标对象后,需要做什么
最后,最重要的,就是在xml中创建通知、目标对象的bean以及关联关系。

1、xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"    xsi:schemaLocation="           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd       ">    <!-- 目标类 -->    <bean id = "computer" class="springaop.Computer">    </bean>    <!-- 通知,即代理后要做什么 -->    <bean id = "interceptor" class="springaop.Interceptor">    </bean>    <!-- 绑定通知和拦截点 -->    <bean id="sleepAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">    <property name="advice" ref="interceptor"/>    <property name="pattern" value=".*calculate"/>    </bean>    <!-- 生成自动代理 -->    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/></beans>

2、接口

package springaop;public interface Cal {    public void calculate(String data);}

3、目标实现类

package springaop;public class Computer implements Cal{    @Override    public void calculate(String data) {        System.out.println("i am computer data="+data);    }}

4、通知

package springaop;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;import org.springframework.aop.MethodBeforeAdvice;public class Interceptor  implements MethodBeforeAdvice,AfterReturningAdvice{    @Override    public void before(Method method, Object[] args, Object target)            throws Throwable {        System.out.println("before... method="+method.getName()+" args="+args);    }    @Override    public void afterReturning(Object returnValue, Method method,            Object[] args, Object target) throws Throwable {        System.out.println("after...");    }}

5、测试方法

package springaop;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AutoSpringAopTest {    @Test    public void testAOP(){        ApplicationContext appCtx = new ClassPathXmlApplicationContext("autospringaop.xml");        Cal cal = (Cal)appCtx.getBean("computer");        cal.calculate("jianghuiwen");    }}

四、输出及总结
这里写图片描述

整个spring aop的核心思想,就是代理,具体说,就是为spring容器中的bean,创建一个代理proxy,该代理proxy持有bean的引用,该代理proxy还绑定了一些自定义的逻辑,在调用该bean的方法的时候,就会执行proxy的业务逻辑。

五、应用遐想
springaop能干什么?很多很多,只要你能想得到。
例如,对某些指定的方法打印日志、计算指定方法的执行时间、计算方法的执行链路、缓存、方法修饰、打印参数、远程调用、异常统一处理、调用统计、指定方法的返回值统计

0 0
原创粉丝点击