Spring基于AspectJ的简单AOP demo
1 demo的工程
1.1pom.xml引入spring和AspectJ的必要框架
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.0.9.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency> </dependencies> |
1.2项目结构
2 定义切面类
切面类,即为各业务方法提供的非业务相关的公共方法,如日志,安全或事务等,本例以记录日志说明为demo。
2.1Spring DI配置类
所有需要DI的类本例以java config为实现,XML的忽略
@Configuration @ComponentScan @EnableAspectJAutoProxy public class AopLogConfig{
@Bean public AopLog aopLog() { return new AopEventLog(); } } |
说明:
- @EnableAspectJAutoProxy
切面类定义了@Aspect,并不能实现真正的切面功能,需要由java config使其为切面的自动代理(加此注解),且为切面类定义一个bean,否则如果不以此注解,则需要在切面类中加此注解。
2.2 切面接口:日志类
public interface AopLog{ void log(); }
@Component @Aspect public class AopEventLog implements AopLog { @Pointcut("execution(** cn.aoe.iccc.ylin.extend.aop.TransService.*Trans(..))") public void logTrans() { }
@Before("logTrans()") public void log() { System.out.println("Event log for translation will be create : " + new Date()); } } |
3 切面类实现的两种方式
首先切面类需要加@Aspect注解,然后如果加了注解:@EnableAspectJAutoProxy后,则无需在java config中再声明此注解和定义bean类,切面类具体代码都不变化,具体如下方案二选一即可:
3.1 方案一:切面类的aspect的自动代理
@Component @Aspect public class AopEventLog implements AopLog {
@Pointcut("execution(** cn.aoe.iccc.ylin.extend.aop.TransService.*Trans(..))") public void logTrans() { }
@Before("logTrans()") public void log() { System.out.println("Event log for translation will be create : " + new Date()); } }
@Configuration @ComponentScan @EnableAspectJAutoProxy public class AopLogConfig{
@Bean public AopLog aopLog() { return new AopEventLog(); } } |
3.2 方案二:Java config的aspect的自动代理
@Configuration @ComponentScan public class AopLogConfig{
}
@Component @Aspect @EnableAspectJAutoProxy public class AopEventLog implements AopLog {
@Pointcut("execution(** cn.aoe.iccc.ylin.extend.aop.TransService.*Trans(..))") public void logTrans() { }
@Before("logTrans()") public void log() { System.out.println("Event log for translation will be create : " + new Date()); } }
|
4 业务类
这里以所有以Trans为结尾命名的所有方法在被调用前为例说明
public interface TransService{ void addTrans(); int delTrans(); }
@Component public class AccountService implements TransService { public void addTrans() { execute(); System.out.println("On " + new Date() + ", add a translate for account"); }
public int delTrans() { execute(); System.out.println("Noticition : a translate for account is deleted"); return 0; } }
private void execute() { try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } |
5. 切面类的测试
利用spring 测试框架
5.1 测试类代码
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=AopLogConfig.class) public class TestTransLog{
@Autowired private TransService ser;
@Test public void testTransLog() { assertNotNull(ser); ser.addTrans(); ser.delTrans(); } } |
5.2 测试结果
Event log for translation will be create : Tue Jul 09 16:43:41 CST 2019 On Tue Jul 09 16:43:42 CST 2019, add a translate for account Event log for translation will be create : Tue Jul 09 16:43:42 CST 2019 Noticition : a translate for account is deleted |
6 你也来试试,good luck!