Spring学习日记(1):https://blog.csdn.net/qq_53477661/article/details/124195726?spm=1001.2014.3001.5501
使用AspectJ基于XML的AOP(面向切面编程)实现
1,创建新的Java项目,在其中导入jar包
通过New→Source Folder新建一个名为lib的文件夹,并且把jar包复制在里面
jar包链接:https://pan.quark.cn/s/a3db8d80f7f7
通过右键lib Build Path→Add to Build Path 添加到环境中
2,在src下创建aop包,并且在该包下创建dao,Test,Aspect 3个包
3,在dao包下创建接口UserDao和其实现类UserDaoImpl
UserDao
package aop.dao;
public interface UserDao {
public void insert();
public void delete();
}
UserDaoImpl
package aop.dao;
public class UserDaoImpl implements UserDao {
@Override
public void insert() {
System.out.println("模拟插入数据....");
}
@Override
public void delete() {
System.out.println("模拟删除数据....");
}
}
可以看到,在UserDao里 我创建了两个方法 模拟插入和删除数据。
4,在Aspect包下创建MyAspect类,并对其进行编写
MyAspect
package aop.Aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
/*
* 前置通知 before
*/
public void myBefore(JoinPoint joinPoint) {
System.out.println("验证权限。。。");
System.out.println("目标类:"+joinPoint.getTarget());
System.out.println("被织入的方法名:"+joinPoint.getSignature().getName());
}
/*
* 后置通知,返回成功
*/
public void myAfterReturning(JoinPoint joinPoint) {
System.out.println("写入日志");
}
/*
* 环绕通知,前后都要织入
*/
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("开启事务。。。");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("关闭事务。。。");
return proceed;
}
/*
* 最终通知
*/
public void myAfter(JoinPoint joinPoint) {
System.out.println("释放系统资源。。。");
}
/*
* 异常通知,处理异常,并且输出异常信息
*/
public void myThrows(JoinPoint joinPoint,Throwable e ) {
System.out.println("异常信息:"+e.getMessage());
}
}
可以看到,我定义了5中不同类型的方法来通知,在通知中用JoinPoint接口及其子接口ProceedingJoinPoint作为参数来获得目标对象的类名/目标方法名和目标方法参数等。
需要注意的是,环绕通知必须接受一个类型为ProceedingJoinPoint的参数,返回值也必须是Object类型,并且必须抛出异常。异常通知中可以转入Throwable类型的参数来输出异常信息
5,创建并编写applicationContext.xml
在src下通过New→Spring Bean Configuration File新建一个xml文件
点击next选中 aop,beans,context
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"
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="userdao" class="aop.dao.UserDaoImpl" />
<bean id="myaspect" class="aop.Aspect.MyAspect"/>
<aop:config>
<aop:aspect ref="myaspect">
<aop:pointcut expression="execution(* aop.dao.*.*(..))" id="myPointCut"/>
<aop:before method="myBefore" pointcut-ref="myPointCut"/>
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut"/>
<aop:around method="myAround" pointcut-ref="myPointCut"/>
<aop:after method="myAfter" pointcut-ref="myPointCut"/>
<aop:after-throwing method="myThrows" pointcut-ref="myPointCut" throwing="e"/>
</aop:aspect>
</aop:config>
</beans>
新建两个bean来获取UserDao和MyAspect的路径
(关于execution(* aop.dao.*.*(..))的意思就是对aop包下的dao包下的所有类,方法生效)
通过编辑<aop:before>,<aop:after-runturing>,<aop:around>,<aop:after>,<aop:after-throwing>来调用MyAspect里的对应方法。
6,在Test包下创建tst.java测试类并进行编写,查看输出结果
tst
package aop.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import aop.dao.UserDao;
public class tst {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userdao = (UserDao) context.getBean("userdao");
userdao.insert();
}
}