SpringFramework(4)

3AOP

1Aspect-oriented Programming

l         补充OOP

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

l         模块化关系

l         用法:

?         持久化

?         事务管理

?         安全

?         日志管理

?         调试

2AOP概念

l         Aspect:模块化关系(concern

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

l         Advice:在具体joinpoint做的动作

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

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

3Pointcut

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不需要使用带参数的方法

4Pointcut实现

l         正则表达式

<bean id="gettersAndSettersPointcut"

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

<property name="patterns">

<list>

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

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

</list>

</property>

</bean>

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

5Advice

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;

}

}

6Advice类型

l         Around Advice(如前面的例子)

l         Before Advice

l         Throws Advice

l         After returning Advice

l         Introduction Advice

7Spring 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>

8ProxyFactory

l         使用ProxyFactory获得Advised对象

?         定义应用的pointcutsadvices

?         以代理对象返回interceptor

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

l         编程方式创建AOP代理

ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);

factory.addInterceptor(myMethodInterceptor);

factory.addAdvisor(myAdvisor);

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

9ProxyFactoryBean

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         InterceptorsAdvisors

<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>

10AutoProxy

l         自动代理的创建:

?         只要定义targets

?         选择的Bean会被自动代理

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

11BeanNameAutoProxyCreator

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>

12AdvisorAutoProxyCreator

l         自动应用Advisorscontext中的Bean

?         每个Advisor对应一个pointcutadvice

?         如果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>

13AOP高级特性

l         元数据驱动的自动代理

l         目标源(TargetSources

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值