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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值