AOP的半自动代理 及 缺点
博客专区 > T-Brain 的博客 > 博客详情
AOP的半自动代理 及 缺点
T-Brain 发表于2年前
AOP的半自动代理 及 缺点
  • 发表于 2年前
  • 阅读 6
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

AOP的通知类型:

aop联盟 定义 aop通知类型,spring 对 aop联盟规范支持。

aop联盟定义5种通知

前置通知 org.springframework.aop.MethodBeforeAdvice

在目标方法执行前实施增强

后置通知 org.springframework.aop.AfterReturningAdvice

在目标方法执行后实施增强

环绕通知 org.aopalliance.intercept.MethodInterceptor

在目标方法执行前后实施增强

异常抛出通知 org.springframework.aop.ThrowsAdvice

在方法抛出异常后实施增强

引介通知 org.springframework.aop.IntroductionInterceptor(了解)对一个类进行增强(添加方法或属性等)

在目标类中添加一些新的方法和属性

如果使用aop联盟规范进行aop开发,所有的通知必须实现接口。(底层为了确定通知方法名称)


AOP的半自动代理(不带有切入点的切面---所有方法)

1.切面类

    需要总结:

            需要根据AOP联盟确定一个通知类型:这里使用环绕通知(环绕通知需要手动开启方法)

            所以切面类随便写,随便实现一个通知类型,重写里面的invok方法在,通过参数调用

                    proceed()执行目标类,前后可以写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.mickeymouse.proxy;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
  * 切面类:包含两个通知(增强)
          环绕通知必须手动执行方法
  * @author Mickey-Mouse
  *
  */
public class MyAspect implements MethodInterceptor {
     public Object invoke(MethodInvocation mi) throws Throwable {
         System.out.println( "已校验是否符合身份" );
         //环绕通知必须手动执行方法
         Object object = mi.proceed();
         System.out.println( "方法已经执行完--->后处理" );
         return object;
     }
}
2.目标类(已实现接口)
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.mickeymouse.proxy;
public class ProductsServiceImpl implements ProductsService {
     /**
      * 目标类:
      * 里面有两个连接点
      */
     public void addProducts(){
         System.out.println( "添加商品成功" );
     }
     public void updateProducts(){
         System.out.println( "修改商品成功" );
     }
}
3.半自动代理XML配置

  与AOP的自动代理的区别在于:

       半自动代理没有使用AOP约束,要手动配置代理类与目标类的关系

      半自动代理是基于ProxyFactoryBean的代理类:

            缺点:

                    * 配置麻烦:

                    * 需要为每一个要增强的类配置一个ProxyFactoryBean.(只要有增强,就需要写一个ProxyFactoryBean的配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<? xml version = "1.0" encoding = "UTF-8" ?>
        xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop = "http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
<!-- bean definitions here -->
     <!-- 半自动代理模式 -->
     <!-- 生成切面类 -->
     < bean id = "myAspect" class = "com.mickeymouse.proxy.MyAspect" />
     <!-- 生成目标类 -->
     < bean id = "productsService" class = "com.mickeymouse.proxy.ProductsServiceImpl" />
     <!-- 让Spring来创建代理工厂对象 -->
     < bean id = "proxyFactoryBean" class = "org.springframework.aop.framework.ProxyFactoryBean" >
         <!-- 设置目标类 -->
         < property name = "target" ref = "productsService" ></ property >
         <!-- 设置切面类"名字" -->
         < property name = "interceptorNames" value = "myAspect" ></ property >
         <!-- 设置切面类需要连接的接口(optimize与接口二选一即可,Spring可以自动识别,接口就动态代理,没有就CGLIB) -->
         < property name = "proxyInterfaces" value = "com.mickeymouse.proxy.ProductsService" ></ property >
         <!-- 是否强制使用使用CGLIB -->
         < property name = "optimize" value = "true" ></ property >
     </ bean >
</ beans >

测试类:

1
2
3
4
5
6
7
@Test
     public void test1(){
         ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml" );
         ProductsService bean = applicationContext.getBean( "proxyFactoryBean" ,ProductsService. class );
         bean.addProducts();
         bean.updateProducts();
     }

结果:



AOP的半自动代理:(配置带有切入点的切面---->个别方法)(了解)

配置文件:(其他部分是一样的 , 同上)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<? xml version = "1.0" encoding = "UTF-8" ?>
        xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
     
     <!-- Spring帶有切入点的切面=============== -->
     
     <!-- 配置目标类 -->
     < bean id = "customerDao" class = "com.itheima.spring.demo4.CustomerDao" />
     
     <!-- 配置通知:(环绕通知) -->
     < bean id = "myAroundAdvice" class = "com.itheima.spring.demo4.MyAroundAdvice" />
     
     <!-- 配置带有切入点的切面 -->
     < bean id = "myAdvisor" class = "org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
         <!-- 表达式: 正则表达式 : .:任意字符  *:任意次数-->
<!-- 拦截所有方法 -->
<!--         <property name="pattern" value=".*"/> -->
<!-- 只拦截update方法 -->
<!--         <property name="pattern" value="com\.itheima\.spring\.demo4\.CustomerDao\.update"/> -->
<!-- 拦截update和delete方法 -->
<!--         <property name="patterns" value="com\.itheima\.spring\.demo4\.CustomerDao\.update,com\.itheima\.spring\.demo4\.Cus            tomerDao\.delete"/> -->
         <!-- 拦截所有以save和update结束名的方法 -->
         < property name = "patterns" value = ".*save.*,.*update.*" />
         <!-- 配置增强 -->
         < property name = "advice" ref = "myAroundAdvice" />
     </ bean >
     
     <!-- 配置生成代理 -->
     < bean id = "proxyFactoryBean" class = "org.springframework.aop.framework.ProxyFactoryBean" >
         <!-- 配置目标 -->
         < property name = "target" ref = "customerDao" />
         <!-- 配置代理目标类 -->
         < property name = "proxyTargetClass" value = "true" />
         <!-- 配置拦截的名称 -->
         < property name = "interceptorNames" value = "myAdvisor" />
     </ bean >
</ beans >



共有 人打赏支持
粉丝 2
博文 44
码字总数 46138
×
T-Brain
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: