SpringFramework(4)

王朝java/jsp·作者佚名  2006-01-30
窄屏简体版  字體: |||超大  

3、AOP

(1)Aspect-oriented Programming

l 补充OOP

l 分解问题的各个方面(或关系)

l 模块化关系

l 用法:

? 持久化

? 事务管理

? 安全

? 日志管理

? 调试

(2)AOP概念

l Aspect:模块化关系(concern)

l Joinpoint:程序执行时的一个点

l Advice:在具体joinpoint做的动作

l Pointcut:一个Advice应该激活的指定joinpoint集合

l Introduction:添加方法或域到Advice类中

(3)Pointcut

l 一个Advice应该激活的指定joinpoint集合

public interface Pointcut {

ClassFilter getClassFilter();

MethodMatcher getMethodMatcher();

}

public interface ClassFilter {

boolean matches(Class clazz);

}

public interface MethodMatcher {

boolean matches(Method m, Class targetClass);

boolean matches(Method m, Class targetClass, Object[] args);

boolean isRuntime();

}

限制pointcut为一组target类;静态pointcuts不需要使用带参数的方法

(4)Pointcut实现

l 正则表达式

<bean id="gettersAndSettersPointcut"

class="org.springframework.aop.support.RegexpMethodPointcut">

<property name="patterns">

<list>

<value>.*\.get.*</value>

<value>.*\.set.*</value>

</list>

</property>

</bean>

方法名全路经匹配Perl5正则表达式

(5)Advice

l 在具体joinpoint做的动作

public interface MethodInterceptor extends Interceptor {

Object invoke(MethodInvocation invocation) throws Throwable;

}

Spring使用包围joinpoint的拦截器(Interceptor)链来实现Advice

l 例子:

public class DebugInterceptor implements MethodInterceptor {

public Object invoke(MethodInvocation invocation)

throws Throwable {

System.out.println(">> " + invocation); // before

Object rval = invocation.proceed();

System.out.println("<< Invocation returned"); // after

return rval;

}

}

(6)Advice类型

l Around Advice(如前面的例子)

l Before Advice

l Throws Advice

l After returning Advice

l Introduction Advice

(7)Spring Advisors

l PointcutAdvisor = Pointcut + Advice

l 每个内建的Advice都有一个Advisor

l 例子:

<bean id="gettersAndSettersAdvisor"

class="...aop.support.RegexpMethodPointcutAroundAdvisor">

<property name="interceptor">

<ref local="interceptorBean"/>

</property>

<property name="patterns">

<list>

<value>.*\.get.*</value>

<value>.*\.set.*</value>

</list>

</property>

</bean>

(8)ProxyFactory

l 使用ProxyFactory获得Advised对象

? 定义应用的pointcuts和advices

? 以代理对象返回interceptor

? 使用Java动态代理或CGLIB2(可以代理接口和类)

l 编程方式创建AOP代理

ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);

factory.addInterceptor(myMethodInterceptor);

factory.addAdvisor(myAdvisor);

MyBusinessInterface b = (MyBusinessInterface)factory.getProxy();

(9)ProxyFactoryBean

l 用来获得Bean的代理

l 要代理的Bean:

<bean id="personTarget" class="eg.PersonImpl">

<property name="name"><value>Tony</value></property>

<property name="age"><value>51</value></property>

</bean>

PersonImpl实现Person接口

l Interceptors和Advisors:

<bean id="myAdvisor" class="eg.MyAdvisor">

<property name="someProperty"><value>Something</value></property>

</bean>

<bean id="debugInterceptor" class="...aop.interceptor.NopInterceptor">

</bean>

l 代理:

<bean id="person" class="...aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces"><value>eg.Person</value></property>

<property name="target"><ref local="personTarget"/></property>

<property name="interceptorNames">

<list>

<value>myAdvisor</value>

<value>debugInterceptor</value>

</list>

</property>

</bean>

l 使用Bean:

? 客户程序应该获得person Bean,而不是personTarget

? 可以通过应用程序context或编程方式来访问

<bean id="personUser" class="com.mycompany.PersonUser">

<property name="person"><ref local="person" /></property>

</bean>

Person person = (Person) factory.getBean("person");

l 如果是代理类而不是接口

? 将proxyTargetClass设置为true,来替代proxyInterfaces

? 代理要扩展target类(由CGLIB来构造)

<bean id="person" class="...aop.framework.ProxyFactoryBean">

<property name="proxyTargetClass"><value>true</value></property>

<property name="target"><ref local="personTarget"/></property>

<property name="interceptorNames">

<list>

<value>myAdvisor</value>

<value>debugInterceptor</value>

</list>

</property>

</bean>

(10)AutoProxy

l 自动代理的创建:

? 只要定义targets

? 选择的Bean会被自动代理

l 不需要为每个target Bean使用ProxyFactoryBean

(11)BeanNameAutoProxyCreator

l 使用Bean名选择targets

<bean id="employee1" class="eg.Employee">...</bean>

<bean id="employee2" class="eg.Employee">...</bean>

<bean id="myInterceptor" class="eg.DebugInterceptor"/>

<bean id="beanNameProxyCreator"

class="...aop.framework.autoproxy.BeanNameAutoProxyCreator">

<property name="beanNames"><value>employee*</value></property>

<property name="interceptorNames">

<list>

<value>myInterceptor</value>

</list>

</property>

</bean>

(12)AdvisorAutoProxyCreator

l 自动应用Advisors到context中的Bean

? 每个Advisor对应一个pointcut和advice

? 如果pointcut应用到Bean,就会被advice拦截

l 有助于保持同一个advice应用到多个事务对象的一致性

l 不可能获得没有advised的对象

l 例子:

<bean id="debugInterceptor" class="app.DebugInterceptor"/>

<bean id="getterDebugAdvisor"

class="...aop.support.RegexpMethodPointcutAdvisor">

<constructor-arg>

<ref bean="debugInterceptor"/>

</constructor-arg>

<property name="pattern"><value>.*\.get.*</value></property>

</bean>

这个Advisor应用debugInterceptor到任何类的所有get方法

<bean id="autoProxyCreator"

class="...aop.framework.autoproxy.AdvisorAutoProxyCreator">

<property name="proxyTargetClass"><value>true</value></property>

</bean>

(13)AOP高级特性

l 元数据驱动的自动代理

l 目标源(TargetSources)

? 热交换目标源:当允许调用者保持他的引用时,允许切换代理的Bean

? 目标源池:维护相同实例的池,在方法激活时释放对象到池中

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航