Spring中面向切面编程的两种方式:XML文件和Annotation的方式进行AOP开发
下面是基于Annotation的方式,代码如下
//以下为声明切面,基于Annotation的方式实现AOP功能
@Aspect
public class MyInterceptor {
@Pointcut("execution(* cn.itcast.service.impl.PersonServiceBean.*(..))")
private void anyMethod(){}//声明一个切入点
@Before("anyMethod()")
public void doAccessCheck(){
System.out.println("这是前置通知");
}
@AfterReturning("anyMethod()")
public void doAfterReturning(){
System.out.println("这是后置通知");
}
}
在配置文件做如下配置
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy/>
<bean id = "MyInterceptor" class="cn.itcast.service.MyInterceptor"></bean>
<bean id="personService" class ="cn.itcast.service.impl.PersonServiceBean"></bean>
</beans>
最后在junit测试中实例化容器,测试AOP功能是否实现
public class SpringAOPTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
// 实例化容器
public void interceptorTest() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService");
personService.save("xxx");
}
}
使用环绕通知(可进行权限拦截)
@Aspect
public class MyInterceptor {
@Pointcut("execution(* cn.itcast.service.impl.PersonServiceBean.*(..))")
private void anyMethod(){}//声明一个切入点
@Before("anyMethod()")
public void doAccessCheck(){
System.out.println("这是前置通知");
}
@AfterReturning("anyMethod()")
public void doAfterReturning(){
System.out.println("这是后置通知");
}
@After("anyMethod()")
public void doAfter(){
System.out.println("这是最终通知");
}
@AfterThrowing("anyMethod()")
public void doAfterThrowing(){
System.out.println("这是例外通知");
}
@Around("anyMethod()")//环绕通知.一般用来做权限拦截
public Object doBasicProfiling(ProceedingJoinPoint pjp)throws Throwable{
//使用一个if(){}可做权限拦截,有权限则执行pjp.proceed()方法
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
return result;
}
}
//以下为控制台输出:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
这是前置通知
进入方法
这是save方法
这是后置通知
这是最终通知
退出方法
得到输入参数的返回结果和抛出的异常,并打印在控制台上
//以下为声明切面
@Aspect
public class MyInterceptor {
@Pointcut("execution(* cn.itcast.service.impl.PersonServiceBean.*(..))")
private void anyMethod(){}//声明一个切入点
@Before("anyMethod() && args(name)")
public void doAccessCheck(String name){
System.out.println("这是前置通知:" + name);
}
@AfterReturning(pointcut="anyMethod()" , returning="result")
public void doAfterReturning(String result){
System.out.println("这是后置通知:"+ result);
}
@After("anyMethod()")
public void doAfter(){
System.out.println("这是最终通知");
}
@AfterThrowing(pointcut="anyMethod()",throwing="e")
public void doAfterThrowing(Exception e){
System.out.println("这是例外通知:"+ e);
}
@Around("anyMethod()")//环绕通知.一般用来做权限拦截
public Object doBasicProfiling(ProceedingJoinPoint pjp)throws Throwable{
//使用一个if(){}可做权限拦截,有权限则执行pjp.proceed()方法
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
return result;
}
}
public class PersonServiceBean implements PersonService {
@Override
public void save(String name) {
throw new RuntimeException("i love Exception");
// System.out.println("这是save方法");
}
@Override
public void update(String name,Integer id ) {
System.out.println("这是update方法");
}
@Override
public String getPersonName(Integer id) {
return "yyy";
}
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
// 实例化容器
public void interceptorTest() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService");
personService.save("jxlgdx");
// personService.getPersonName(3);
}
}