Spring的学习(十二)——SpringAOP
一、基于xml
需要导入jar包:aopalliance.jar、aspectjweaver.jar、spring-aop-x.x.x.RELEASE.jar、spring-aspects-x.x.x.RELEASE.jar
建立User:
package com.little.entity;
public class User {
private int uid;
private String uname;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
建立UserService接口:
package com.little.service;
import com.little.entity.User;
public interface UserService {
// 添加 user
public void addUser(User user);
// 删除 user
public void deleteUser(int uid);
}
实现UserServiceImpl接口:
package com.little.service.impl;
import com.little.entity.User;
import com.little.service.UserService;
public class UserServiceImpl implements UserService {
public void addUser(User user) {
System.out.println("增加 User");
}
public void deleteUser(int uid) {
System.out.println("删除 User");
}
}
建立通知类:
package com.little.adivce;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAdivce {
/**
//前置通知:目标方法运行之前调用
//后置通知(如果出现异常不会调用):在目标方法运行之后调用
//环绕通知:在目标方法之前和之后都调用
//异常拦截通知:如果出现异常,就会调用
//后置通知(无论是否出现 异常都会调用):在目标方法运行之后调用
*/
// 前置通知
public void before() {
System.out.println("这是前置通知");
}
// 后置通知
public void afterReturning() {
System.out.println("这是后置通知(方法不出现异常)");
}
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("这是环绕通知之前部分!!");
Object object = point.proceed(); // 调用目标方法
System.out.println("这是环绕通知之后的部分!!");
return object;
}
public void afterException() {
System.out.println("异常通知!");
}
public void after() {
System.out.println("这也是后置通知,就算方法发生异常也会调用!");
}
}
配置applicationContext-aop.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
<bean name="userService" class="com.little.service.impl.UserServiceImpl" />
<!--配置通知对象 -->
<bean name="myAdvice" class="com.little.adivce.MyAdivce" />
<!-- 配置将增强织入目标对象 -->
<aop:config>
<!--
com.itqf.spring.service.UserServiceImpl
1 2 3 4
1: 修饰符 public/private/* 可忽略
2: 返回值 String/../*
3: 全限定类名 类名 ..代表不限层数 *ServiceImpl
4: (..)
-->
<aop:pointcut id="pc" expression="execution(* com.little.service.impl.*ServiceImpl.*(..))" />
<aop:aspect ref="myAdvice">
<aop:before method="before" pointcut-ref="pc" />
<aop:after-returning method="afterReturning" pointcut-ref="pc" />
<aop:around method="around" pointcut-ref="pc" />
<aop:after-throwing method="afterException" pointcut-ref="pc" />
<aop:after method="after" pointcut-ref="pc" />
</aop:aspect>
</aop:config>
</beans>
测试:
package com.little.springAOPTest;
import com.little.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringAOPTest {
@Test
public void test1() {
// TODO 测试切面引入
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-aop.xml");
UserService userServiceImpl = context.getBean("userService", UserService.class);
userServiceImpl.addUser(null);
userServiceImpl.deleteUser(11);
}
}
二、基于注解
创建配置文件:applicationContext-aop-annotation.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
<bean name="userService" class="com.little.service.impl.UserServiceImpl" />
<!--配置通知对象 -->
<bean name="myAdvice" class="com.little.adivce.MyAdivce1" />
<!-- 配置将增强织入目标对象 使用注解的方式 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
创建通知MyAdivce1:
package com.little.adivce;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class MyAdivce1 {
/**
//前置通知:目标方法运行之前调用
//后置通知(如果出现异常不会调用):在目标方法运行之后调用
//环绕通知:在目标方法之前和之后都调用
//异常拦截通知:如果出现异常,就会调用
//后置通知(无论是否出现 异常都会调用):在目标方法运行之后调用
*/
@Pointcut("execution(* com.little.service.impl.*ServiceImpl.*(..))")
public void pc() {
}
// 前置通知
@Before("MyAdivce1.pc()")
public void before() {
System.out.println("这是前置通知");
}
// 后置通知
@AfterReturning("execution(* com..*ServiceImpl.*(..))")
public void afterReturning() {
System.out.println("这是后置通知(方法不出现异常)");
}
@Around("execution(* com..*ServiceImpl.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("这是环绕通知之前部分!!");
Object object = point.proceed(); // 调用目标方法
System.out.println("这是环绕通知之后的部分!!");
return object;
}
@AfterThrowing("execution(* com..*ServiceImpl.*(..))")
public void afterException() {
System.out.println("异常通知!");
}
@After("execution(* com..*ServiceImpl.*(..))")
public void after() {
System.out.println("这也是后置通知,就算方法发生异常也会调用!");
}
}
测试:
@Test
public void test2() {
// TODO 测试切面引入
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-aop-annotation.xml");
UserService userServiceImpl = context.getBean("userService", UserService.class);
userServiceImpl.addUser(null);
userServiceImpl.deleteUser(11);
}