版权声明:转载请注明原始链接 https://blog.csdn.net/sswqzx/article/details/83989557
1、基于注解AOP入门案例
1.2、创建工程引入依赖
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</dependencies>
1.3、编写Spring配置文件
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启Spring注解扫描-->
<context:component-scan base-package="com.day03"> </context:component-scan>
<!--开启aspectj自动代理-->
<aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
</beans>
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout, file
1.4、创建接口和实现类
UserDao.java
package com.day03.dao;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 21:48 2018/11/11
*/
public interface UserDao {
public abstract void save();
public abstract Integer delete();
public abstract Integer update(int a, int b);
public abstract void list();
}
UserDaoImpl.java
package com.day03.dao.Impl;
import com.day03.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 21:48 2018/11/11
*/
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save方法。。。。。。。。。。。");
}
@Override
public Integer delete() {
System.out.println("delete方法。。。。。。。。。。。");
return 100;
}
@Override
public Integer update(int a, int b) {
System.out.println("update......................");
int c = a + b;
return c;
}
@Override
public void list() {
//int a = 10/0;
System.out.println("List...........................");
}
}
1.5、编写切面类
MyAspectAnno.java
package com.day03.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 9:30 2018/11/13
*/
@Component
@Aspect //表示该类是一个切面类
public class MyAspectAnno {
}
1.6、编写测试类
MyTestAnno.java
package com.day03.test;
import com.day03.dao.UserDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 9:32 2018/11/13
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class MyTestAnno {
@Autowired
private UserDao userDao;
//前置通知
@Test
public void tes1(){
userDao.save();
}
//后置通知
@Test
public void test2(){
userDao.delete();
}
//环绕通知
@Test
public void test3(){
userDao.update(5,10);
}
//异常通知
@Test
public void test4(){
userDao.list();
}
}
2、用注解来配置各种通知
前置通知、后置通知、环绕通知、异常通知、最终通知
MyAspectAnno.java切面类
package com.day03.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 9:30 2018/11/13
*/
@Component
@Aspect //表示该类是一个切面类
public class MyAspectAnno {
/**
* 前置通知方法 应用场景: 权限控制 (权限不足,抛出异常)、 记录方法调用信息日志 joinPoint:连接点,指的是被增强的那个方法
* @param jp
*/
@Before("execution(* com.day03.dao.Impl.UserDaoImpl.save(..))")
public void before(JoinPoint jp){
String username = "admin";
if (!"user".equals(username)){
throw new RuntimeException("你没有对类"+jp.getTarget().getClass().getName()+"中的方法"+jp.getSignature().getName()+"访问权限!");
}
}
/**
* 后置通知方法 应用场景: ATM取款机取款后,自动下发短信 参数result:被增强那个方法的返回值
* returning属性指定目标方法返回值的名字
*/
@AfterReturning(value = "execution(* com.day03.dao.Impl.UserDaoImpl.delete(..))",returning = "result")
public void afterRunnings(JoinPoint jp,Object result){
System.out.println("你在ATM机上取了:"+result+"元");
}
/**
* 环绕通知方法 应用场景:事务处理
* proceedingJoinPoint
* 正在执行的连接点
* @return
*/
@Around("execution(* com.day03.dao.Impl.UserDaoImpl.update(..))")
public Object around(ProceedingJoinPoint pjp){
System.out.println("开启事务");
Object[] args = pjp.getArgs();//获取参数
Object proceed = null;
try {
proceed = pjp.proceed(args);
// int a = 10/0;
System.out.println("proceed = " + proceed);
System.out.println("提交事务");
} catch (Throwable throwable) {
System.out.println("回滚事务");
}
return proceed;
}
/**
* 异常通知方法、应用:异常处理
* @param ex
* 目标方法抛出的异常
*/
@AfterThrowing(value = "execution(* com.day03.dao.Impl.UserDaoImpl.list(..))",throwing = "ex")
public void afterThroing(JoinPoint jp , Throwable ex){
throw new RuntimeException("在这个类:"+jp.getTarget().getClass().getName()+"中的方法"+jp.getSignature().getName()+"抛出异常"+ex.getMessage());
}
/**
*最终通知方法 应用场景:释放资源 (关闭文件、 关闭数据库连接、 网络连接、 释放内存对象 )
*@param joinPoint 被增强的那个方法
*/
@After("execution(* com.day03.dao.Impl.UserDaoImpl.list(..))")
public void after(JoinPoint joinPoint){
System.out.println("释放资源、对应的类为"+joinPoint.getTarget().getClass().getName()+"方法为:"+joinPoint.getSignature().getName());
}
}
UserDaoImpl.java
package com.day03.dao.Impl;
import com.day03.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 21:48 2018/11/11
*/
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save方法。。。。。。。。。。。");
}
@Override
public Integer delete() {
System.out.println("delete方法。。。。。。。。。。。");
return 100;
}
@Override
public Integer update(int a, int b) {
System.out.println("update......................");
int c = a + b;
return c;
}
@Override
public void list() {
//int a = 10/0;
System.out.println("List...........................");
}
}
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启Spring注解扫描-->
<context:component-scan base-package="com.day03"> </context:component-scan>
<!--开启aspectj自动代理-->
<aop:aspectj-autoproxy> </aop:aspectj-autoproxy>
</beans>
MyTestAnno.java
package com.day03.test;
import com.day03.dao.UserDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 9:32 2018/11/13
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class MyTestAnno {
@Autowired
private UserDao userDao;
//前置通知
@Test
public void tes1(){
userDao.save();
}
//后置通知
@Test
public void test2(){
userDao.delete();
}
//环绕通知
@Test
public void test3(){
userDao.update(5,10);
}
//异常通知
@Test
public void test4(){
userDao.list();
}
}