程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Spring進階之路(11)-使用Aspectj切面配置和XML配置文件方式實現切面編程

Spring進階之路(11)-使用Aspectj切面配置和XML配置文件方式實現切面編程

編輯:JAVA綜合教程

Spring進階之路(11)-使用Aspectj切面配置和XML配置文件方式實現切面編程


異常

在使用的時候,遇到了部分的異常,我用的是最新的Spring版本,Spring-4.2.5版本的,首先確保你的配置文件中引入了下面紅色部分。

 xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

然後需要導入的包有幾個:

 

1. aspectjrt.jar

2.aspectjweaver.jar

3.aopalliance-1.0.jar

 

我在使用的時候由於沒有使用第三個jar包導致了異常信息如下:

 

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:228)
	at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:687)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:523)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
	at com.siti.spring20160315aop.MainTest.main(MainTest.java:9)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1098)
	... 13 more


 

下面開始使用AspectJ進行切面配置

 

 

AspectJ注解方式進行切面配置

 

定義四個接口,下面讓WangYang類實現這個Person的接口,並實現其中的方法。

 

package com.siti.spring20160315aop;

public interface Person {

	void say();
	void sayName(String name);
	String saySth(String name);
	void sayEx();
}

 

 

其中saySth這個方法設置了返回值,這個地方會被AfterReturning織入,然後sayEx方法為了測試故意利用空指針異常,測試AfterThrowing會不會被織入。

 

package com.siti.spring20160315aop;

public class WangYang implements Person{

	@Override
	public void say() {
		System.out.println("wy!");
	}

	@Override
	public void sayName(String name) {
		System.out.println("name-->" + name);
	}

	@Override
	public String saySth(String name) {
		System.out.println("name-->" + name);
		return name;
	}

	@Override
	public void sayEx() {
		Object obj = null;
		obj.equals("1");
	}
}

 

面向切面編程AspectJ的實現,主要方式如下,其中,after通知主要用於釋放資源,afterReturning通知可以對返回值進行更改,afterThrowing通知可以進行異常捕獲生成異常記錄,before這個通知可以進行參數的校驗之類的。
package com.siti.spring20160315aop;

import java.util.Arrays;

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;

@Aspect
public class MyInterceptor {

	@Pointcut("execution(* com.siti.spring20160315aop.WangYang.*(..))")
	public void anyMethod(){}
	
	@Before("anyMethod()")
	public void checkMessage(JoinPoint joinPoint){
		System.out.println("@Before-check!!!");
		System.out.println("@Before-目標對象為:" + joinPoint.getTarget());
		System.out.println("@Before-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@Before-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	@AfterReturning(pointcut = "anyMethod()", returning = "obj")
	public void checkReturn(JoinPoint joinPoint, Object obj){
		System.out.println("@AfterReturning-目標方法返回值:" + obj);
		System.out.println("@AfterReturning-生成日志");
		
		System.out.println("@AfterReturning-目標對象為:" + joinPoint.getTarget());
		System.out.println("@AfterReturning-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@AfterReturning-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	@After("anyMethod()")
	public void checkAfter(JoinPoint joinPoint){
		System.out.println("@After-釋放資源!");
		
		System.out.println("@After-目標對象為:" + joinPoint.getTarget());
		System.out.println("@After-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@After-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	@Around("anyMethod()")
	public Object checkAround(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("@Around!");
		
		Object[] args = joinPoint.getArgs();
		if(args != null && args.length > 0 && args[0].getClass() == String.class){
			args[0] = "@Around" + args[0];
		}
		Object result = joinPoint.proceed(args);
		if(result != null && result.getClass() == String.class){
			result = result + "--wy";
		}
		return result;
	}
	
	@AfterThrowing(throwing = "ex", pointcut = "anyMethod()")
	public void checkAfterThrowing(Throwable ex){
		System.out.println("@AfterThrowing-異常拋出!");
		System.out.println("@AfterThrowing-異常日志!");
		
	}
	
	
}

 

配置文件需要將我們自己寫的這個切面的類,在配置文件中進行“注冊”。

 



	
	
	
	
測試:

 

 

package com.siti.spring20160315aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160315.xml");
		Person wy = context.getBean("wy", Person.class);
		wy.say();
		wy.sayName("wangyang-");
		String str = wy.saySth("hello--");
		System.out.println("str的值:" + str);
		// wy.sayEx();// 拋出異常的測試
	}
}




 

XML配置文件的方式


 

基於配置文件配置的方式和前面的注解的方式基本上類似的,這裡只是將,改動的地方列出來,不做介紹了。

配置文件如下:

 



	
	
		
		
		
		
			
			
			
			
		
		
			
			
	
	
	

package com.siti.spring20160315aopwithxml;

import java.util.Arrays;

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

public class MyInterceptor {

	public void anyMethod(){}
	
	public void checkMessage(JoinPoint joinPoint){
		System.out.println("@Before-check!!!");
		System.out.println("@Before-目標對象為:" + joinPoint.getTarget());
		System.out.println("@Before-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@Before-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	public void checkReturn(JoinPoint joinPoint, Object obj){
		System.out.println("@AfterReturning-目標方法返回值:" + obj);
		System.out.println("@AfterReturning-生成日志");
		
		System.out.println("@AfterReturning-目標對象為:" + joinPoint.getTarget());
		System.out.println("@AfterReturning-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@AfterReturning-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	public void checkAfter(JoinPoint joinPoint){
		System.out.println("@After-釋放資源!");
		
		System.out.println("@After-目標對象為:" + joinPoint.getTarget());
		System.out.println("@After-目標方法:" + joinPoint.getSignature().getName());
		System.out.println("@After-目標方法的參數:" + Arrays.toString(joinPoint.getArgs()));
	}
	
	public Object checkAround(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("@Around!");
		
		Object[] args = joinPoint.getArgs();
		if(args != null && args.length > 0 && args[0].getClass() == String.class){
			args[0] = "@Around" + args[0];
		}
		Object result = joinPoint.proceed(args);
		if(result != null && result.getClass() == String.class){
			result = result + "--wy";
		}
		return result;
	}
	
	public void checkAfterThrowing(Throwable ex){
		System.out.println("@AfterThrowing-異常拋出!");
		System.out.println("@AfterThrowing-異常日志!");
		
	}
	
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved