zoukankan      html  css  js  c++  java
  • Spring AOP实战例子与springmvc整合不起效果的解决办法

    在使用AOP之前,首先我们先了解一下什么是AOP吧。在网上很多人将AOP翻译为“面向切面编程”,什么是面向切面?与面向对象有什么区别呢?

    在回答这两个问题之前,我们先要明白切面的概念。

    切面由切点与增强组成,它既包括了横切逻辑的定义,也包括了连接点的定义,springAOP就是负责实施切面的框架,它将切面定义的横切逻辑

    织入到切面所指定的连接点中。

    这时候就要问了:什么是切点?什么是增强?

    先看个例子,在例子中再为大家一一解释。

    例子:在服务行业,热情问好,带人礼貌是每一个成熟的服务员应有的规范。

    建立一个接口  Water.java 方法:问好与服务,greetTo(),serviceTo()

    package test.aop;
    /**
     * 
     * @author 作者: wcy  
     * @version 创建时间:Mar 3, 2015 4:27:12 PM
     * @Description: TODO(一个服务生向顾客问候接待)
     */
    public interface Waiter {
    
    	public void greetTo(String name);
    	public void serviceTo(String name);
    }
    

     那么接下来一个生涩的,训练不足的服务员,他只会生硬的打招呼,这对客人的服务可不好。

    建立一个类NativeWater.java

    package test.aop.impl;
    
    import test.aop.Waiter;
    
    /**
     * 
     * @author 作者: wcy  
     * @version 创建时间:Mar 3, 2015 4:29:53 PM
     * @Description: TODO(一个训练不足的服务生)
     */
    public class NativeWater implements Waiter{
    
    	public void greetTo(String name) {
    		System.out.println("greet to :"+name+"....");
    		
    	}
    
    	public void serviceTo(String name) {
    		System.out.println("service to :"+name+"....");
    		
    	}
    
    }
    

     这样子不好,我们必须对训练不足的服务员进行规范,在打招呼之前先热情问好

    package test.aop.impl;
    
    import java.lang.reflect.Method;
    import org.springframework.aop.MethodBeforeAdvice;
    
    /**
     * 
     * @author 作者: wcy  
     * @version 创建时间:Mar 3, 2015 4:32:39 PM
     * @Description: TODO(服务生打招呼前,友好问候别人)
     */
    public class GreetingBeforeAdvice implements MethodBeforeAdvice{
    
    	public void before(Method arg0, Object[] arg1, Object arg2)
    			throws Throwable {
    		String clientName = (String) arg1[0];
    		System.out.println("How are you ? Mr."+clientName+"~~~~~");
    	}
    
    }
    

     好,已经对其进行规范了,我们就要测试一下:

    package test.aop.impl;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.aop.BeforeAdvice;
    import org.springframework.aop.framework.ProxyFactory;
    
    import test.aop.Waiter;
    
    /**
     * 
     * @author 作者: wcy  
     * @version 创建时间:Mar 3, 2015 4:40:14 PM
     * @Description: TODO(强制服务生要热情问候顾客)
     */
    public class BeforeAdviceTest {
    
    	private Waiter waiter;
    	private BeforeAdvice advice;
    	private ProxyFactory pf;
    	
    	@Before
    	public void init(){
    		waiter = new NativeWater();
    		advice = new GreetingBeforeAdvice();
    		pf = new ProxyFactory();//Spring工厂提供的代理类
    		pf.setTarget(waiter);  	//设置代理目标
    		pf.addAdvice(advice);//为代理目标添加增强
    	}
    	
    	@Test
    	public void test01(){
    		
    		Waiter proxy = (Waiter) pf.getProxy();
    		proxy.greetTo("xiaoyu");
    		proxy.serviceTo("xiaolian");
    	}
    }
    

     运行的结果如下:

    How are you ? Mr.xiaoyu~~~~~
    greet to :xiaoyu....
    How are you ? Mr.xiaolian~~~~~
    service to :xiaolian....

    好了,这就是一个面向切面的简单例子,那我们就要总结一下了,面向切面需要什么东西。

    1、目标类。也就是上文所说的NativeWater.java 该类是一个训练不足的服务生,需要我们对其进行规范,所以要有规范类。

    2、增强类。需要实现AOP的前置增强(同样也有后置、环绕等增强),就是规范类,对服务生进行规范。

    3、测试类。要为其进行代理,所以要有AOP的代理工厂。

    详细的AOP资料,百度很多我就不一一介绍了。

    先说一下AOP的执行流程吧。

    当我们调用某个定义了AOP的目标类中某个方法时,spring容器会为目标类生成代理类,这生成的方法有2种,一是:jdk的动态代理,使用它必须要有接口;二是CGLib代理,

    代理类融合了原类和增强类,它可能与原类具有同样的接口,也可能是原类的子类,所以当我们访问原类的方法的时候,会先访问增强类,再到原类。

    好了,以上就说到这。

    spring与springmvc整合出现AOP不起作用的原因:

    1、spring与springmvc加载配置文件是不同步的,springmvc加载文件对注解进行扫描后,所有的注解都被扫到容器里面,当spring同样加载配置文件扫描注解时,因为容器中已经

    存在Service类,那么CGLib代理或jdk动态代理就不对它进行代理了,直接导致了applicationContext.xml中的事务不起作用,出现异常,事务不会滚。

    2、解决方法:Spring MVC 和 Spring 整合的时候,SpringMVC的springmvc.xml文件中 配置扫描包,不要包含 service的注解,Spring的applicationContext.xml文件中 配置扫描包时,不要包含controller的注解,如下所示:
    SpringMVC的xml配置:

    	<!--1、 注解探测器,对注解进行扫描 -->
    	<context:component-scan base-package="com">
    		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    	</context:component-scan>
    

    同样的,spring的applicationContext.xml配置文件也一样,不要扫描@Controller注解

    	 <!-- 注解扫描器 -->
    	 <context:component-scan base-package="com">
    	 	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    	 </context:component-scan>
    

     工作完成。

  • 相关阅读:
    ubuntu 启用apache运行状态信息查看
    Loadrunner生成随机字符
    Linux 如何在 vi 里搜索关键字
    Loadrunnber 报错误:Error memory violation : Exception ACCESS_VIOLATION received.的一种情况
    Could not load file or assembly 'XXX' or one of its dependencies.
    C# 显示年月日星期
    C#中timer类的用法
    详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb
    C# winform DataGridView 的18种常见属性
    WdatePicker日历控件使用方法
  • 原文地址:https://www.cnblogs.com/wcyBlog/p/4342077.html
Copyright © 2011-2022 走看看