Spring 9:aop:config标签

aop:config标签

   使用aop的专用标签来完成相关的配置.(AOP标签库)
   其中主要表现是使用AspectJ的expression的操作:
  

    execution(modifiers-pattern ret-type-pattern
    declaring-type-pattern name-pattern(param-pattern)


     throws-pattern)除了返回类型模式,名字模式和参数模式以外,
    所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次
    匹配一个连接点。 你会使用的最频繁的返回类型模式是 *,它代表了匹
    配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方
    法。名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分
    命名模式。 参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方
    法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。
    模式 (*) 匹配了一个接受一个任何类型的参数的方法。 模式
    (*,String) 匹配了一个接受两个参数的方法,第一个可以是任
    意类型,第二个则必须是String类型
   
   注意在使用之前需要在xml文件的beans标签中加入新的schame文件:并在Eclipse中进行关联配置
  

    

    
    下面给出一些常见切入点表达式的例子。  

 
    1)任意包下的任意类中的公共方法的执行:  
      

  execution(public * *(..))


    2)任何一个以“set”开始的方法的执行:  
     

   execution(* set*(..))


    3)AccountService 接口的任意方法的执行:    
      

 execution(* com.briup.service.AccountService.*(..))


    4)定义在service包里的任意方法的执行:  
 

       execution(* com.briup.service.*.*(..))


                
    5)定义在service包或者子包里的任意方法的执行:  
    

    execution(* com.briup.service..*.*(..))
    
    execution(* com.briup.service..*.*(..)) or execution(* com.briup.dao..*.*(..))

    注意:
        1.从spring容器中拿代理对象的时候也是要用目标对象的名字来拿。
        2.没有实现任何接口的目标对象也能产生代理对象。
    
 

   
    
        
        
        

        
        
    
    

     注意: 如果这样配置则是强制使用CGLIB方式进行代理

例:
1.配置文件xml


  
        
        
        
        
       
          
	
		
		
		
		
		
	



2.测试类:

package com.briup.aop.spring.aopConfig;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class aopConfigTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/aopConfig/aopConfig.xml");
		BookService bs=
		cp.getBean("target",BookService.class);
		bs.saveBook(1, "lisi");
		bs.list();
		ProductService ps=
				cp.getBean("target1",ProductService.class);
		ps.saveProduct(1, "lisi");
		ps.getProduct();
	}
}

※ 自定义通知类(自定义方法)

需要:aspectjweaver.jar包

在一个切面类中定个多个方法,根据xml文件的配置每个方法都可以织入到切入点的
不同位置,并且advice是在aop的标签中进行配置,不需要再写对应的advice类了
    例如:
  

 //这个类相当于我们之前的切面类
    //只不过这个切面类中有很多方法都可以织入到切入点上面
    //我们可以控制把这里的任何一个方法织入到任何一个切入点上面
    public class XmlHandler {
        
        public void beforeTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" before...");
        }
        
        
        public void afterTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" after...");
        }
        
        public void afterReturningTest(JoinPoint p){
            
            System.out.println(p.getSignature().getName()+" afterReturning");
            
        }
        
        //在和aroundAdvice结合的时候,这个方法一定要加上这个ProceedingJoinPoint类型的参数
        public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
            //JoinPoint对象不能调用连接点所表示的方法
            //ProceedingJoinPoint能调用连接点所表示的方法 pjp.proceed()
            System.out.println(pjp.getSignature().getName()+" is start..");
            //调用到连接点方法
            Object obj = pjp.proceed();
            System.out.println(pjp.getSignature().getName()+" is end..");
            return obj;
        }
        
        public void throwingTest(JoinPoint p,Exception ex){
            System.out.println(p.getSignature().getName()+" is throwing..."+ex.getMessage());
            
        }
    }
    
    xml文件配置:
    
    
    
    
            
    
    
    
    
    
    
        
        
        
        
        
            
            

            
            

            
            

            

            
            

        
    


    
    注意: 如果这样配置则是强制使用CGLIB方式进行代理

例:
1.自定义通知类

package com.briup.aop.spring.defineAopConfig;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/*
 * 自定义通知类(自定义的方法)
 */
public class DefineNoticeAdvice {
		/*
		 * 前置通知,
		 * 参数必须是joinpoint
                 * 
		 */
	public void beforeTest(JoinPoint point){
		System.out.println("before......");
	}
	/*
	 * 后置通知
	 */
	public void after(JoinPoint point){
		//获取方法的镜像
//		System.out.println(point.getSignature());
//		//获取方法镜像的名字
//		System.out.println(
//				point.getSignature().getName());
		//获取目标对象方法执行的参数
//		System.out.println(
//				Arrays.toString(point.getArgs()));
		//获取目标对象
//		System.out.println(point.getTarget());
//		System.out.println(point.getThis());
		System.out.println("after....");
	}
	public void afterReturn(JoinPoint point){
		System.out.println("after1.....");
	}
	public Object 
		around(ProceedingJoinPoint point){
//		System.out.println(point.getTarget());
//		System.out.println(point.getThis());
//		System.out.println(point.getSignature());
//		System.out.println(point.getArgs());
		Object obj=null;
		try {
			System.out.println("before.....");
			//执行目标对象中的方法
			obj=point.proceed();
			System.out.println("after....");
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}
	/*
	 * 异常通知的方法
	 * 第一个参数joinPoint
	 * 第二个参数异常类
	 */
	public void 
	throwE(JoinPoint point,Exception ex){
		System.out.println(
				"exception..."+ex.getMessage());
	}
}




2.配置文件xml


  
          
         
       	 
         
         
          
          	
          	
         	
         	
         		
         		 
         		
         		
         				
         				 
         				
         				
         				
         				
         				
         	
          
    
 
 
 
       
3. 测试类:

package com.briup.aop.spring.defineAopConfig;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class defineNoticeaopConfigTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/defineAopConfig/defineaopconfig.xml");
		BookService bs=
		cp.getBean("target",BookService.class);
		bs.saveBook(1, "lisi");
		bs.list();
//		ProductService ps=
//				cp.getBean("target1",ProductService.class);
//		ps.saveProduct(1, "lisi");
//		ps.getProduct();
	}
}


※ 使用注解配置AOP:其实就是在上面的类XmlHandler中加入上注解,然后去掉xml中的aop标签配置,这里把类改名为AnnotationHandler,
   

例子:
    @Component
    @Aspect
    public class AnnotationHandler {
        /*
         * 在一个方法上面加上注解来定义切入点
         * 这个切入点的名字就是这个方法的名字
         * 这个方法本身不需要有什么作用
         * 这个方法的意义就是:给这个 @Pointcut注解一个可以书写的地方
         * 因为注解只能写在方法、属性、类的上面,并且方法名作为切入点的名字
         * */
        @Pointcut("execution(public * com.briup.aop.service..*.*(..))")
        public void myPointCut(){}
        
        //注:这里面的所有方法的JoinPoint类型参数都可以去掉不写,如果确实用不上的话
        @Before("myPointCut()")
        public void beforeTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" before...");
        }
        
        
        /*
         * @After和@AfterReturning
         *
         * @After标注的方法会在切入点上的方法结束后被调用(不管是不是正常的结束).
         * @AfterReturning标注的方法只会在切入点上的方法正常结束后才被调用.
         * */
        @After("myPointCut()")
        public void afterTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" after...");
        }
        @AfterReturning("myPointCut()")
        public void afterReturningTest(JoinPoint p){
            
            System.out.println(p.getSignature().getName()+" afterReturning");
            
        }
        
        @Around("myPointCut()")
        public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
            System.out.println(pjp.getSignature().getName()+" is start..");
            //调用连接点的方法去执行
            Object obj = pjp.proceed();
            System.out.println(pjp.getSignature().getName()+" is end..");
            return obj;
        }
        
        
        
        //在切入点中的方法执行期间抛出异常的时候,会调用这个 @AfterThrowing注解所标注的方法
        @AfterThrowing(value="myPointCut()",throwing="ex")
        public void throwingTest(JoinPoint p,Exception ex){
            System.out.println(p.getSignature().getName()+" is throwing..."+ex.getMessage());
            
        }
        
    }
    
    xml配置:注意给例子中使用的其他的类上面也使用注解
    
    

    注意:这样配置则是强制使用CGLIB进行代理

例:
1.

package com.briup.pojo;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

@Component("target")
//@Controller
//@Service
//@Repository
public class BookServiceImpl
	implements BookService{
	
	@Override
	public void saveBook(long id, String name) {
		// TODO Auto-generated method stub
		System.out.println("saveBook....");
		//int i=10/0;
	}

	@Override
	public String get(long id) {
		// TODO Auto-generated method stub
		System.out.println("get....");
		return "test...ok";
	}

	@Override
	public void list() {
		// TODO Auto-generated method stub
		System.out.println("list....");
	}

	@Override
	public void setTest() {
		// TODO Auto-generated method stub
		System.out.println("set.....");
	}

	@Override
	public int getAge() {
		// TODO Auto-generated method stub
		System.out.println("getAge()....");
		return 23;
	}

}


package com.briup.pojo;

import org.springframework.stereotype.Component;

@Component("target1")
public class ProductService {
	public void saveProduct(long id,String name){
		System.out.println("saveProduct...");
	}
	public int getProduct(){
		System.out.println("getProduct....");
		return 33;
	}
}


2.自定义通知类

package com.briup.aop.spring.AnnoAopConfig;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/*
 * 自定义通知类(自定义的方法)
 * @Aspect表示单前类中的方法全是
 * 作用切面上的通知
 * 1.注解的方式构建切面(方法)
 * 2.通知上面加入注解 
 */
@Component
@Aspect
public class AnnoNoticeAdvice {
		/*
		 * 构建切面的方法,切面的名字
		 * 就是methodName(),
		 * 该方法不使用
		 */
		//@Pointcut(value="")
		@Pointcut("execution(* com.briup.pojo.*.save*(..))")
		public void mypointcut(){}
		/*
		 * 前置通知,
		 * 参数必须是joinpoint
		 * @Before注解该方法前置通知
		 * 参数是切面的名字
		 */
	@Before("mypointcut()")
	public void beforeTest(JoinPoint point){
		System.out.println("before......");
	}
	/*
	 * 后置通知
	 */
	@After("mypointcut()")
	public void after(JoinPoint point){
		//获取方法的镜像
//		System.out.println(point.getSignature());
//		//获取方法镜像的名字
//		System.out.println(
//				point.getSignature().getName());
		//获取目标对象方法执行的参数
//		System.out.println(
//				Arrays.toString(point.getArgs()));
		//获取目标对象
//		System.out.println(point.getTarget());
//		System.out.println(point.getThis());
		System.out.println("after....");
	}
	@AfterReturning("mypointcut()")
	public void afterReturn(JoinPoint point){
		System.out.println("after1.....");
	}
	@Around("mypointcut()")
	public Object 
		around(ProceedingJoinPoint point){
//		System.out.println(point.getTarget());
//		System.out.println(point.getThis());
//		System.out.println(point.getSignature());
//		System.out.println(point.getArgs());
		Object obj=null;
		try {
			System.out.println("before.....");
			//执行目标对象中的方法
			obj=point.proceed();
			System.out.println("after....");
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}
	/*
	 * 异常通知的方法
	 * 第一个参数joinPoint
	 * 第二个参数异常类
	 * @AfterThrowing中throwing对应的名字和参数
	 * 异常的名字一致
	 */
	@AfterThrowing(value="mypointcut()",
			throwing="ex")
	public void 
	throwE(JoinPoint point,Exception ex){
		System.out.println(
				"exception..."+ex.getMessage());
	}
}




3.配置文件


  
          
         
       
        
        
    
 
 
 
4.测试类:

package com.briup.aop.spring.AnnoAopConfig;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class AnnoaopConfigTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/AnnoAopConfig/annoaopconfig.xml");
		BookService bs=
		cp.getBean("target",BookService.class);
		bs.saveBook(1, "lisi");
		bs.list();
//		ProductService ps=
//				cp.getBean("target1",ProductService.class);
//		ps.saveProduct(1, "lisi");
//		ps.getProduct();
	}
}

 

你可能感兴趣的:(SSM(Spring))