zoukankan      html  css  js  c++  java
  • SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对照注解方式的优缺点)

    接上一篇

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


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


    SecurityHandler这个通知类能够换成安全性检測、日志管理等等。


    <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
    
    import org.aspectj.lang.JoinPoint;
    
    
    public class SecurityHandler {
    	
    	private void checkSecurity(JoinPoint joinPoint) {
    		for (int i=0; i<joinPoint.getArgs().length; i++) {
    			System.out.println(joinPoint.getArgs()[i]);
    		}
    		
    		System.out.println(joinPoint.getSignature().getName());
    		
    		System.out.println("-------checkSecurity-------");
    	}		
    }
    </span></span></span>


    UserManager接口


    <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
    
    public interface UserManager {
    
    	public void addUser(String username, String password);
    	
    	public void delUser(int userId);
    	
    	public String findUserById(int userId);
    	
    	public void modifyUser(int userId, String username, String password);
    }
    </span></span></span>

    UserManagerImpl接口的实现
    <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
    
    public class UserManagerImpl implements UserManager {
    
    	public void addUser(String username, String password) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.add()--------");
    	}
    
    	public void delUser(int userId) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.delUser()--------");
    	}
    
    	public String findUserById(int userId) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.findUserById()--------");
    		return "张三";
    	}
    
    	public void modifyUser(int userId, String username, String password) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.modifyUser()--------");
    	}
    
    //	private void checkSecurity() {
    //		System.out.println("-------checkSecurity-------");
    //	}
    }
    </span></span></span>

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


    <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	     xmlns:aop="http://www.springframework.org/schema/aop"
    	     xmlns:tx="http://www.springframework.org/schema/tx"
    	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
        <!-- 强制使用CGLIB代理 -->  
        <!--      
    	<aop:aspectj-autoproxy proxy-target-class="true"/>
    	 -->
    	 
    	<bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
    	<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
    	
    	<aop:config>
    		<aop:aspect id="securityAspect" ref="securityHandler">
    			<!--
    			以add开头的方法 
    			<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
    			 -->
    			 <!-- 
    			 com.bjpowernode.spring包下全部的类全部的方法
    			<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/>
    			 --> 
    			<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/> 
    			<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
    		</aop:aspect>
    	</aop:config>
    </beans>
    </span></span></span>

    Clientclient的调用


    <span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.bjpowernode.spring;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Client {
    
    	public static void main(String[] args) {
    		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    		
    		UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");
    		userManager.addUser("张三", "123");
    		
    	}
    
    }
    </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风格中我们能够编写例如以下的内容:



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

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


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

    注意: XML风格AOP尽管不支命名连接点的声明,可是,能够使用例如以下形式处理,例如以下配置:


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


    总结

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

         

  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6812803.html
Copyright © 2011-2022 走看看