SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

前端之家收集整理的这篇文章主要介绍了SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

上一篇

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP


本文采用强制的CGLB代理方式


SecurityHandler这个通知类可以换成安全性检测、日志管理等等。


  1. <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4.  
  5.  
  6. public class SecurityHandler {
  7. private void checkSecurity(JoinPoint joinPoint) {
  8. for (int i=0; i<joinPoint.getArgs().length; i++) {
  9. System.out.println(joinPoint.getArgs()[i]);
  10. }
  11. System.out.println(joinPoint.getSignature().getName());
  12. System.out.println("-------checkSecurity-------");
  13. }
  14. }
  15. </span></span></span>


UserManager接口


  1. <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
  2.  
  3. public interface UserManager {
  4.  
  5. public void addUser(String username,String password);
  6. public void delUser(int userId);
  7. public String findUserById(int userId);
  8. public void modifyUser(int userId,String username,String password);
  9. }
  10. </span></span></span>

UserManagerImpl接口的实现
  1. <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
  2.  
  3. public class UserManagerImpl implements UserManager {
  4.  
  5. public void addUser(String username,String password) {
  6. //checkSecurity();
  7. System.out.println("---------UserManagerImpl.add()--------");
  8. }
  9.  
  10. public void delUser(int userId) {
  11. //checkSecurity();
  12. System.out.println("---------UserManagerImpl.delUser()--------");
  13. }
  14.  
  15. public String findUserById(int userId) {
  16. //checkSecurity();
  17. System.out.println("---------UserManagerImpl.findUserById()--------");
  18. return "张三";
  19. }
  20.  
  21. public void modifyUser(int userId,String password) {
  22. //checkSecurity();
  23. System.out.println("---------UserManagerImpl.modifyUser()--------");
  24. }
  25.  
  26. // private void checkSecurity() {
  27. // System.out.println("-------checkSecurity-------");
  28. // }
  29. }
  30. </span></span></span>

applicationContext.xml中进行配置(<!-- 强制使用CGLIB代理 --> )


  1. <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><?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="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
  9. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  10. <!-- 强制使用CGLIB代理 -->
  11. <!--
  12. <aop:aspectj-autoproxy proxy-target-class="true"/>
  13. -->
  14. <bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
  15. <bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
  16. <aop:config>
  17. <aop:aspect id="securityAspect" ref="securityHandler">
  18. <!--
  19. 以add开头的方法
  20. <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
  21. -->
  22. <!--
  23. com.bjpowernode.spring包下所有的类所有的方法
  24. <aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/>
  25. -->
  26. <aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/>
  27. <aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
  28. </aop:aspect>
  29. </aop:config>
  30. </beans>
  31. </span></span></span>

Client客户端的调用


  1. <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
  2.  
  3. import org.springframework.beans.factory.beanfactory;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class Client {
  7.  
  8. public static void main(String[] args) {
  9. beanfactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
  10. UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");
  11. userManager.addUser("张三","123");
  12. }
  13.  
  14. }
  15. </span></span></span>

最终效果




AOP两种代理的区别

Jdk基于接口实现:JDK动态代理对实现了接口的类进行代理。

  • CGLIB基于继承:CGLIB代理可以对类代理,主要对指定的类生成一个子类,因为是继承,所以目标类最好不要使用final声明。
  • 如果目标对象实现了接口,默认情况下采用JDK的动态代理实现AOP,也可以强制使用CGLB生成代理实现;
  • 如果目标对象没有实现接口,那么必须引入CGLB,spring会在JDK的动态代理和CGLB代理之间切换

通常情况下,鼓励使用jdk代理,因为业务一般都会抽象出一个接口,而且不用引入新的东西。如果是遗留的系统,以前没有实现接口,那么只能使用CGLIB。

一般情况下优先采用JDK动态代理,虽然其效率似乎比不上CGLIB代理,但是其对象用完之后可以正常释放。但是CGLIB代理每代理一个对象,都会产生一个新类。而类一旦载入JVM,按照大部分JVM的机制,这些新类占用的内存不会释放。J2EE程序一般运行时间都很长,内存上会有一些压力。


XML和AspectJ注解方式配置优缺点对比


用XML风格,则所有的切面、切点、通知等配置都写在一个或几个Spring配置文件里。这样的好处是,从配置文件中,就可以很清晰的看出系统中的有哪些切面,某个切面里使用那个的通知(advice)以及通知(advice)作用的切点。而在AspectJ风格中,在java程序中标识切面则显得凌乱、模糊。


在什么情况下使用注解形式的AOP?或者说使用注解来实现AOP有哪些优点呢?

1. XML风格的AOP仅仅支持"singleton"切面实例模型,而采用AspectJ风格的AOP则
没有这个限制。

2.XML风格的AOP中是不支持命名连接点的声明,而采用AspectJ风格的AOP则没有这个限制。不太理解的看下面实例代码
在@AspectJ风格中我们可以编写如下的内容



  1. <span style="font-size:18px;"> @Pointcut(execution(* get*()))
  2. public void propertyAccess() {}
  3. @Pointcut(execution(org.xyz.Account+ *(..))
  4. public void operationReturningAnAccount() {}
  5. @Pointcut(propertyAccess() && operationReturningAnAccount())
  6. public void accountPropertyAccess() {} </span>

在XML风格中,我们不能使用'&&'字符来连接命名连接点,如下:


  1. <span style="font-size:18px;"> <aop:pointcut id="propertyAccess"
  2. expression="execution(* get*())"/>
  3. <aop:pointcut id="operationReturningAnAccount"
  4. expression="execution(org.xyz.Account+ *(..))"/>
  5. <!-- 错误的配置 -->
  6. <aop:pointcut id="accountPropertyAccess"
  7. expression="propertyAccess && operationReturningAnAccount"/> </span>

注意: XML风格AOP虽然不支命名连接点的声明,但是,可以使用如下形式处理,如下配置:


  1. <span style="font-size:18px;"> <aop:pointcut id="propertyAccess"
  2. expression="execution(* get*())"/>
  3. <aop:pointcut id="operationReturningAnAccount"
  4. expression="execution(org.xyz.Account+ *(..))"/>
  5. <aop:pointcut id="accountPropertyAccess"
  6. expression="execution(* get*()) and execution(org.xyz.Account+ *(..))"/> </span>


总结

这两种方法都实现了AOP,提高了我们的程序代码复用率,很好的体现了抽象带来的好处,两者相互补充,相互借鉴,我们根据实际情况适当的选取和决策,在系统开发环境下适合开发的流程才是最重要的,

猜你在找的XML相关文章