SpringAop代理模式笔记

aop:面向切面编程(分为代理类和目标类)
  需求:把原本要放一起运行的代码由于不符合设计 对他们进行进行解耦,在运行时在动态的结合在一起.

核心原理:就是利用了jdk的动态和cglib的动态代理
动态代理分为:dynamic和cglib

<bean name="beforeAdvice" class="com.briup.aop.before.BeforeAdvice">
  <!-- 注入切面类 -->
  <property name="logger" ref="logger"></property>
</bean>


xml:标签中的命名空间中的声明中后的url路径只起唯一标识作用 jtsl标签同理

普通代理模式:
  1)静态代理(通常用于学习,在程序运行前,代理类的.class文件就已经存在了):
    代理类和委托类实现同一接口,重写接口的方法,里面加入委托类的相同方法实现,以及需要新加入的实现,(在放入ioc中拿取)
  2)动态代理:(在程序运行时,代理类是运用了反射技术或字节码技术动态创建而成的)
    1.jdk自带的动态代理:(用于实现了接口的类 具体通过实现InvocationHandler接口的类 中的invoke方法中加入新的需求)
    2.cglib代理(用于没有实现接口的类,通过生成子类, 调用委托类的方法时,加入一些需求)
    aop(面向切面编程:将需求变成切面类(aspect),委托类中的方法变成连接点(joinpoint);通知/拦截器(advice)控制织入(wave)到方法执行前后位置或抛异常的时候;

    增强器(adivsor用来删选那些方法为连接点)(没有增强器时,默认委托类中的所有方法都为连接点),切入点(JoinPoint):为一组连接点的集合

aop普通手动(org.springframework.aop.framework.ProxyFactoryBean)代理工厂:
<bean name="proxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 注入目标对象 -->
<property name="target" ref="target"></property>

<!-- 注入目标对象所实现的接口 可以有多个接口 -->
<property name="proxyInterfaces">
<list>
  <value>com.briup.aop.service.IAccountService</value>
</list>
</property>

<!-- advice表示拦截委托类里的所有方法,-->
<!-- 配置advisor 增强器-->
<!-- 作用:筛选要拦截(要代理)的方法 -->
<bean name="advisor"
  class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice-->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法(连接点) -->
<property name="patterns">
<list>
  <value>.*bankAction</value> 单个字符出现0到多次
</list>
</property>
</bean>
<!-- 配置增强器可指定拦截委托类中的指定方法-->

<!-- 注入advice 可以有多个 也可直接注入advisor-->
<property name="interceptorNames">
<list>
  <value>throwAdvice</value>
</list>
</property>
</bean>


aop自动代理工厂:
1.
1).通过拦截器指定需要拦截的具体方法,
<!-- 配置advisor -->
<!-- 作用:筛选要拦截的方法 -->
<bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice -->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法 -->
<property name="patterns">
<list>
  <value>.*bankAction</value>
</list>
</property>
</bean>
2)配置自动代理工厂,
<!-- 配置代理对象 -->
<!-- 这里使用自动代理的方式 autoproxy -->
<!-- 注意:这不是一个工厂类,所以不能用过proxy来拿代理对象 -->
<bean name="proxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>
3)直接通过委托类名拿到具体的代理对象

2.AutoProxyByName 通过名字进行自动代理:BeanNameAutoProxyCreator类的使用
1)配置拦截器(有无都没关系)
<!-- 配置advisor -->
<!-- 作用:筛选要拦截的方法 -->
<bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入advice -->
<property name="advice" ref="beforeAdvice"></property>
<!-- 注入需要被拦截的目标对象中的方法 -->
<property name="patterns">
<list>
<value>.*bankAction</value>
</list>
</property>
</bean>
2)配置自动代理工厂
<!-- 配置代理对象 -->
<!-- 这里使用自动代理的方式 autoproxybyname -->
<bean name="proxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 注入需要被代理的对象名字 -->
<property name="beanNames">
<list>
<value>target</value>
<value>target2</value>
<value>dao</value>
<value>service*</value>
</list>
</property>

<!-- 注入advice或者advisor -->
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>
3)也是直接通过目标对象名获取代理对象

aop:config标签
<!-- 配置aop的代理 -->
<aop:config>
<!-- 定义一个切入点 并给切入点起名为myPointCut -->
<!-- 切入点是一组连接点的集合 -->
<aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..)) or execution(public * com.briup.aop.service.*.*(..)) or......" id="myPointCut"/>

<!-- 定义哪一个advice在哪一个切入点上面起作用 -->
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="myPointCut" />
</aop:config>

注意:<aop:config proxy-target-class="true"> 如果这样配置则是强制使用CGLIB方式进行代理


<!-- aop:aspect标签:定义切面类 把类中的方法(相当于advice)分别织入到切入点中的各个位置 -->
<!-- 配置切面类 -->
<bean name="handler" class="com.briup.aop.xml.XmlHandler"></bean>
<aop:aspect id="aspect" ref="handler">
<!-- 表示beforeAdvice会把切面类handler中的beforeTest方法织入到名字叫myPointCut的切入点前面 -->
<aop:before method="beforeTest" pointcut-ref="myPointCut"/>

<!-- after表示不管方法是否正常结束都会起作用 -->
<aop:after method="afterTest" pointcut-ref="myPointCut"/>

<!-- after-returning表示方法正常结束才会起作用(抛异常时候不起作用) -->
<aop:after-returning method="afterReturningTest" pointcut-ref="myPointCut"/>

<aop:around method="aroundTest" pointcut-ref="myPointCut"/>

<!-- throwing="ex"表示throwingTest方法中接收异常对象的名字一定要是ex -->
<aop:after-throwing method="throwingTest" pointcut-ref="myPointCut" throwing="ex"/>
</aop:aspect>

猜你喜欢

转载自www.cnblogs.com/nyhhd/p/12547234.html