Spring aop 基于schema的AOP支持及JoinPoint的使用、如何使用CGLIB代理

56 篇文章 0 订阅
ava代码   收藏代码
  1.   

 基于schema的aop只是将配置写到配置文件中。

代码:

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. public interface UserManager {  
  4.   
  5.     public void add(String name, String password);  
  6.     public void del(String id);  
  7.     public void modify(int id ,String name, String password);  
  8. }  

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. public class UserManagerImpl implements UserManager {  
  4.   
  5.     public void add(String name, String password) {  
  6.   
  7.         System.out.println("add method");  
  8.     }  
  9.   
  10.     public void del(String id) {  
  11.         System.out.println("del method");  
  12.     }  
  13.   
  14.     public void modify(int id, String name, String password) {  
  15.         System.out.println("modify method");  
  16.     }  
  17.   
  18. }  

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. public interface MySecurityManager {  
  4.   
  5.     public void checkSecurity();  
  6. }  

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. public class MySecurityManagerImpl implements MySecurityManager {  
  4.     public void checkSecurity() {  
  5.         System.out.println("User security Check");  
  6.     }  
  7.   
  8. }  

 

注意上面的实现类中没有做任何@AspectJ的声明。

配置文件:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.         xmlns:aop="http://www.springframework.org/schema/aop"  
  6.         xmlns:tx="http://www.springframework.org/schema/tx"  
  7.         xsi:schemaLocation="  
  8.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  10.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
  11.           
  12. >  
  13.       
  14.     <bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>  
  15.     <bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>  
  16.     <aop:config>  
  17.         <aop:aspect id="mySecurity" ref="mySecurityManager">  
  18.             <aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />  
  19.             <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>  
  20.         </aop:aspect>  
  21.     </aop:config>  
  22. </beans>  

 

测试类:

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class Client extends TestCase{  
  9.   
  10.     public void testAop(){  
  11.         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
  12.         UserManager userManager = (UserManager)ac.getBean("userManager");  
  13.         userManager.add("zhangshang""123456");  
  14.         userManager.del("23");  
  15.     }  
  16. }  

 结果:

 

Java代码   收藏代码
  1. User security Check  
  2. add method  
  3. User security Check  
  4. del method  

 注意我们配置文件中删除了:<aop:aspectj-autoproxy/>

 

JoinPoint的使用

在上面的checkSecurity方法中,我们没办法得到横切对象方法如add方法的参数。我们使用JoinPoint来解决。

上面示例只需要修改对应的checkSecurity方法即可。如我们修改MySecurityManagerImpl如下:

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. import org.aspectj.lang.JoinPoint;  
  4.   
  5. public class MySecurityManagerImpl implements MySecurityManager {  
  6.     public void checkSecurity(JoinPoint joinPoint) {  
  7.          Object args[] = joinPoint.getArgs();  
  8.          if(args!=null){  
  9.             for (int i = 0; i < args.length; i++) {  
  10.                 System.out.println("args[" +i+"] =" + args[i]);  
  11.             }  
  12.          }  
  13.         System.out.println("User security Check");  
  14.     }  
  15.   
  16. }  

 

我们通过给checkSecurity方法增加JoinPoint joinPoint参数,再通过getArgs方法得到add方法的参数

现在测试Client.java

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class Client extends TestCase{  
  9.   
  10.     public void testAop(){  
  11.         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
  12.         UserManager userManager = (UserManager)ac.getBean("userManager");  
  13.         userManager.add("zhangshang""123456");  
  14.         //userManager.del("23");  
  15.     }  
  16. }  

 

输出如下:

Java代码   收藏代码
  1. args[0] =zhangshang  
  2. args[1] =123456  
  3. User security Check  
  4. add method  

 

我们看到获取了用户名和密码。这种方法在不修改配置文件的条件下即可获得add方法参数。

 

需要注意的是因为spring aop默认采用的是J2SE实现的动态代理机制,而动态代理机制只能对接口代理,所以上面的代码UserManager必须是接口。如果不使用接口则要使用cglib代理,因为cglib代理可以对类实现代理

如何使用cglib代理?

我们可以强制让spring aop使用cglib代理而不是jdk的动态代理

只要在配置文件中将

Java代码   收藏代码
  1. <aop:config proxy-target-class="true">  

 并且增加cglib库到我们的用户自定义库中。

下面来测试:

我们首先删除UserManager接口,也删除MySecurityManager接口(这个接口本来就可以不要)。

修改Client的测试代码。剩下的代码如下所示。

注意我们先不使用cglib测试:

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. public class UserManagerImpl {  
  4.   
  5.     public void add(String name, String password) {  
  6.   
  7.         System.out.println("add method");  
  8.     }  
  9.   
  10.     public void del(String id) {  
  11.         System.out.println("del method");  
  12.     }  
  13.   
  14.     public void modify(int id, String name, String password) {  
  15.         System.out.println("modify method");  
  16.     }  
  17.   
  18. }  

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. import org.aspectj.lang.JoinPoint;  
  4.   
  5. public class MySecurityManagerImpl  {  
  6.     public void checkSecurity(JoinPoint joinPoint) {  
  7.          Object args[] = joinPoint.getArgs();  
  8.          if(args!=null){  
  9.             for (int i = 0; i < args.length; i++) {  
  10.                 System.out.println("args[" +i+"] =" + args[i]);  
  11.             }  
  12.          }  
  13.         System.out.println("User security Check");  
  14.     }  
  15.   
  16. }  

 

Java代码   收藏代码
  1. package com.lwf.aop;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class Client extends TestCase{  
  9.   
  10.     public void testAop(){  
  11.         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
  12.         //UserManager userManager = (UserManager)ac.getBean("userManager");  
  13.         //userManager.add("zhangshang", "123456");  
  14.         //userManager.del("23");  
  15.           
  16.         UserManagerImpl userManager = (UserManagerImpl)ac.getBean("userManager");  
  17.         userManager.add("zhangshang""123456");  
  18.     }  
  19. }  

 

Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.         xmlns:aop="http://www.springframework.org/schema/aop"  
  6.         xmlns:tx="http://www.springframework.org/schema/tx"  
  7.         xsi:schemaLocation="  
  8.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  10.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
  11.           
  12. >  
  13.       
  14.     <bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>  
  15.     <bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>  
  16.     <aop:config >  
  17.         <aop:aspect id="mySecurity" ref="mySecurityManager">  
  18.             <aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />  
  19.             <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>  
  20.         </aop:aspect>  
  21.     </aop:config>  
  22. </beans>  

 测试输出结果:

Java代码   收藏代码
  1. org.springframework.beans.factory.BeanCreationException:   
Java代码   收藏代码
  1. Error creating bean with name 'userManager' defined in class path resource [applicationContext.xml]:   
Java代码   收藏代码
  1. Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException:   
Java代码   收藏代码
  1. Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.   

 我们可以看到删除UserManager接口,而默认情况下使用JDK动态代理又需要该接口,所以报错,提示在这种情况下应该要使用cglib代理。

下面我们使用cglib代理,一加入cglib库,二修改配置文件如下:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.         xmlns:aop="http://www.springframework.org/schema/aop"  
  6.         xmlns:tx="http://www.springframework.org/schema/tx"  
  7.         xsi:schemaLocation="  
  8.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  10.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
  11.           
  12. >  
  13.       
  14.     <bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>  
  15.     <bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>  
  16.     <aop:config proxy-target-class="true">  
  17.         <aop:aspect id="mySecurity" ref="mySecurityManager">  
  18.             <aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />  
  19.             <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>  
  20.         </aop:aspect>  
  21.     </aop:config>  
  22. </beans>  

 

输出结果:

Java代码   收藏代码
  1. args[0] =zhangshang  
  2. args[1] =123456  
  3. User security Check  
  4. add method  

 

通常我们使用JDK的动态代理就可以了,一般我们是对一些之前开发的系统,因为没有接口类,所以考虑使用cglib代理进行增加spring aop 的功能。

Java代码   收藏代码
  1. J2SE动态代理和CGLIB字节码生成代理的区别?  
  2.     * J2SE动态代理只针对接口进行代理,不能针对类  
  3.     * CGLIB是针对类实现代理,主要对指定的类生成一个子类,并覆盖其中的方法,从而实现方法的拦截,  
  4.       因为是通过继承,所以无法为final方法提供代理  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值