实验七:Spring AOP编程
一、实验目的
1.熟悉Spring AOP的JDK动态代理
2.熟悉Spring AOP的CGLib动态代理
3.掌握基于XML的AOP实现
4.掌握基于注解的AOP实现
二、实验内容
1.实现Spring AOP的JDK动态代理
2.实现Spring AOP的CGLib动态代理
3.实现基于XML的AOP
4.实现基于注解的AOP
三、实验步骤
1.实现Spring AOP的JDK动态代理
(1)在项目的pom.xml文件中加载需要用到的spring基础包和spring的依赖包
(2)创建接口
在src\main\java文件夹下创建com\sun\demo01文件夹并创建接口UserDao
public interface UserDao {
public void addUser();
public void deleteUser();
}
(3)创建接口实现类
在src\main\java\com\sun\demo01文件夹中创建UserDao接口的实现类UserDaoImpl
package com.sun.demo01;
public class UserDaoImpl implements UserDao {
public void addUser(){
System.out.println("添加用户");
}
public void deleteUser(){
System.out.println("删除用户");
}
}
(4)创建切面类
在src\main\java\com\sun\demo01文件夹中创建MyAspect切面类
package com.sun.demo01;
public class MyAspect {
public void check_Permissions(){
System.out.println("模拟检查权限...");
}
public void log(){
System.out.println("m模拟记录日志...");
}
}
(5)创建代理类
在src\main\java\com\sun\demo01文件夹中创建MyProxy代理类
package com.sun.demo01;
导入相关包....
public class MyProxy implements InvocationHandler {
private UserDao userDao;
public Object createProxy(UserDao userDao) {
this.userDao = userDao;
ClassLoader classLoader = MyProxy.class.getClassLoader();
Class[] classes = userDao.getClass().getInterfaces();
return Proxy.newProxyInstance(classLoader,classes,this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
MyAspect myAspect = new MyAspect();
myAspect.check_Permissions();
Object obj = method.invoke(userDao, args);
myAspect.log();
return obj;
}
}
(6)创建测试类
在src\main\java\com\sun\demo01文件夹中创建JDKTest测试类
package com.sun.demo01;
public class JDKTest {
public static void main(String[] args) {
MyProxy jdkProxy = new MyProxy();
UserDao userDao = new UserDaoImpl();
UserDao userDao1= (UserDao) jdkProxy.createProxy(userDao);
userDao1.addUser();
userDao1.deleteUser();
}
}
运行结果:
2.实现Spring AOP的CGLib动态代理
(1)创建目标类
在src\main\java文件夹下创建com\sun\demo02文件夹并创建接口UserDao
package com.sun.demo02;
public class UserDao {
public void addUser(){
System.out.println("添加用户");
}
public void deleteUser(){
System.out.println("删除用户");
}
}
(2)创建代理类
在src\main\java\com\sun\demo02文件夹中创建代理类CglibProxy.java
package com.sun.demo02;
导入相关包....
public class CglibProxy implements MethodInterceptor {
public Object createProxy(Object target){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable{
MyAspect myAspect = new MyAspect();
myAspect.check_Permissions();
Object obj = methodProxy.invokeSuper(proxy,args);
myAspect.log();
return obj;
}
}
(3)创建测试类
在src\main\java\com\sun\demo02文件夹中创建测试类CglibTest.java
package com.sun.demo02;
public class CglibTest {
public static void main(String[] args) {
CglibProxy cglibProxy =new CglibProxy();
UserDao userDao= new UserDao();
UserDao userDao1=(UserDao)cglibProxy.createProxy(userDao);
userDao1.addUser();
userDao1.deleteUser();
}
}
运行结果
3.实现基于XML的AOP
(1)导入相关依赖
在pom.xml文件中导入AspectJ框架相关JAR包的依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
(2)创建接口
在src\main\java文件夹下创建com\sun\demo03文件夹并创建接口UserDao
package com.sun.demo03;
public interface UserDao {
public void insert();
public void delete();
public void update();
public void select();
}
(3)创建实现类
在src\main\java\com\sun\demo03文件夹中创建实现类UserDaoImpl.java
package com.sun.demo03;
public class UserDaoImpl implements UserDao{
public void insert(){
System.out.println("添加用户信息");
}
public void delete(){
System.out.println("删除用户信息");
}
public void update(){
System.out.println("更新用户信息");
}
public void select(){
System.out.println("查询用户信息");
}
}
(4)创建定义通知类
在src\main\java\com\sun\demo03文件夹中创建类XmlAdvice.java
package com.sun.demo03;
导入相关包....
public class XmlAdvice {
public void before(JoinPoint joinPoint){
System.out.print("这是前置通知");
System.out.print("目标类是:"+joinPoint.getTarget());
System.out.println(",被织入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
public void afterReturning(JoinPoint joinPoint){
System.out.print("这是返回通知(方法不出现异常时调用)!");
System.out.println("被织入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
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("这是后置通知!");
}
}
(5)创建XML文件用于引入AOP命名空间
在src\main\resources文件夹下创建applicationContext.xml文件
<?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">
<bean name="userDao" class="com.sun.demo03.UserDaoImpl"/>
<bean name="xmlAdvice" class="com.sun.demo03.XmlAdvice"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(*
com.sun.demo03.UserDaoImpl.*(..))"/>
<aop:aspect ref ="xmlAdvice">
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"/>
<aop:after-throwing method="afterException" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
(6)创建测试类
在src\main\java\com\sun\demo03文件夹中创建测试类TestXml.java
package com.sun.demo03;
导入相关包....
public class TestXml {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=context.getBean("userDao",UserDao.class);
userDao.delete();
System.out.println();
userDao.insert();
System.out.println();
userDao.select();
System.out.println();
userDao.update();
}
运行结果
4.实现基于注解的AOP
(1)创建定义通知类
在src\main\java文件夹下创建com\sun\demo04文件夹并创建通知类AnnoAdvice.java
package com.sun.demo04;
引入相关包....
@Aspect
public class AnnoAdvice {
@Pointcut("execution(* com.sun.demo03.UserDaoImpl.*(..))")
public void poincut(){
}
@Before("poincut()")
public void before(JoinPoint joinPoint){
System.out.printf("这是前置通知");
System.out.printf("目标类是"+joinPoint.getTarget());
System.out.println(",被织入增强处理的目标方法为:"+joinPoint.getSignature().getName());
}
@AfterReturning("poincut()")
public void afterReturning(JoinPoint joinPoint){
System.out.print("这是返回通知!");
System.out.println("被织入增强处理的目标方法为:"+
joinPoint.getSignature().getName());
}
@Around("poincut()")
public Object around(ProceedingJoinPoint point) throws Throwable{
System.out.println("这是环绕通知之前的部分!");
Object object = point.proceed();
System.out.println("这是环绕通知之后的部分!");
return object;
}
@AfterThrowing("poincut()")
public void afterException(){
System.out.println("异常通知");
}
@After("poincut()")
public void after(){
System.out.println("这是后置通知!");
}
}
(2)创建XML文件用于引入AOP命名空间
在src\main\resources文件夹下创建applicationContext-Anno.xml文件
<?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">
<bean name="userDao" class="com.sun.demo03.UserDaoImpl"/>
<bean name="AnnoAdvice" class="com.sun.demo04.AnnoAdvice"/>
<aop:aspectj-autoproxy/>
</beans>
(3)创建测试类
在src\main\java\com\sun\demo04文件夹中创建测试类TestAnnotation.java
package com.sun.demo04;
导入相关包...
public class TestAnnotation {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-Anno.xml");
UserDao userDao = context.getBean("userDao",UserDao.class);
userDao.delete();
System.out.println();
userDao.insert();
System.out.println();
userDao.select();
System.out.println();
userDao.update();
}
}
运行结果