Spring4基础 学习笔记(3) ---- AOP(1) ---- 基于Xml

AOP:
术语:
连接点:可以被切面织入的方法(这里的 可以  指的是在容器中注册为连接点)
 
切入点:具体要织入的方法
 
目标对象:要被织入的方法所在的对象
 
通知(Advice):切面的一种实现,可以完成简单的织入功能。定义了织入时间。即增强的业务什么时候实现,主业务之前或者之后
 
          顾问(Advisor):将通知进一步包装。可以选择增强的方法
 
用代理实现AOP:将交叉业务和系统级服务放在代理中。
 
AOP环境搭建:
1)导入jar:
 
2)原来的applicationContext.xml规范
 
 
通知(Advice):AOP
1)MethodBeforeAdvice  : 前置通知
定义实现该接口的类(切面)
注册该类
<!-- 切面 -->
<bean id="before" class="MyMethodBeforeAdvice"/>
注册代理工厂bean,用来提供代理对象,
<bean id="Factory" class="org.springframework.aop.framework.ProxyFactoryBean">
设置工厂的参数:
<property name="targetName" value="someService"/>
或者
<property name="target" ref = "service.ISomeServiceImpl"/>
               
配置切面:
 
<!-- 切面 -->
<property name="interceptorNames" value="before"                      
2)AfterRunningAdvice:后置通知,多了业务方法返回值,其余同上
 
3)MethodInterceptor:环绕通知
public class myMethodInterceptor implements MethodInterceptor {
      @Override
      public Object invoke(MethodInvocation invocation) throws Throwable {
            // TODO Auto-generated method stub
            System.out.println("之前");
          //注意:这个方法返回值是业务里doFirst方法返回值
            Object result = invocation.proceed();     
            System.out.println("之后");
            return result;
      }
}
 
 
 
输出 :
之前
执行doFirst方法
之后
 
参数invocation.proceed方法执行业务方法
 
4)ThrowsAdvice:异常通知
//异常通知
public  class  myThrowsAdvice implements ThrowsAdvice {
      public void afterThrowing(Exception ex) {
            System.out.println("执行异常通知方法" +ex.getMessage() );
      }
}
给对象织入多个切面:
            <property name="interceptorNames">
                  <array>
                        <value>before</value>
                  </array>
            </property>
            
            <!-- <property name="interceptorNames" value="用逗号分割"> -->
 
使用<bean id="Factory" class="org.springframework.aop.framework.ProxyFactoryBean">
这种方式:有接口会生成JDKDynamicProxy对象,没有接口会使用CGLIB动态代理
 
在有接口情况下使用CGLIB代理:
增加一个property-><property name="proxyTargetClass" value="true">  
                    或者:<property name="optimize" value="true">       
 
顾问:选择切入点(Advice所有方法都切入,只是简单实现)
PointcutAdvisor接口常用实现类:
NameMatchMethodPonitcutAdvisor:名称匹配方法切入点顾问
      <!-- 切面 -->
      <bean id="before" class="MyMethodBeforeAdvice"/>
      
      <!-- 注册Advisor -->
      <bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
            <property name="advice" ref="before"/>
            <property name="mappedName" value="doFirst"/>
      </bean>
使用mappedNames匹配多个方法
 
<property name="mappedName" value="*ir*"/>  ---> 使用通配符匹配带有ir的
使用顾问(而不是切面)
<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!-- <property name="targetName" value="someService"/> -->
            <property name="target" ref ="someService"/>
            <!-- 包装切面 -->
            <property name="interceptorNames" value="myAdvisor" />   
</bean>
 
RegexMethodPointcutAdvisor : 正则表达式匹配方法切入点顾问
 
正则表达式:
 
运算符 名称 意义
. 点号 表示任意单个字符
+ 加号 表示前一个字符出现一次或者多次
* 星号 表示前一个字符出现0次或者多次
| A | B   模式A或者模式B 或者
 
      <bean id="myAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
            <property name="advice" ref="before"/>
            <property name="pattern" value=".*i.*"/>          //任意字符出现一次或者多次,使用patterns匹配多个模式     
</bean>
 
注意:pattern匹配的是全限定性方法名,doFirst无法匹配dofirst方法,.*doFirst可以匹配
 
 
问题 : 如果被代理对象有多个,那么代理bean需要多个。
 
自动代理生成器(均继承自bean后处理器BeanPostProcessor,容器中所有Bean在初始化时均会自动执行Bean后处理器中的方法,故其无需id属性):
 
默认advisor自动代理生成器
bean名称自动代理生成器
 
1)默认advisor自动代理生成器:
      <!-- 注册自动代理生成器 -->
      <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
 
缺點:默認使用顧問(容器里配置的顾问),所有bean的顾问指定方法都会织入
 
2)bean名稱自動代理生成器:可以實現對指定bean的切入和指定方法的切入
      <!-- bean名称自动代理生成器 -->
      <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
            <property name="beanNames" value="someService"/>
            <!-- 还能指定切面 -->
            <property name="interceptorNames" value="myAdvisor"/>
      </bean>
posted @ 2018-03-26 22:03  CoderLynn  阅读(226)  评论(0编辑  收藏  举报