目录
一、项目结构
二、pom.xml
<dependencies>
<!-- Spring常用依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
</dependencies>
三、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.by"></context:component-scan>
<!-- 开启spring对注解AOP的支持 -->
<aop:aspectj-autoproxy/>
</beans>
四、log4j日志
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
五、代码
(1)持久层实现类
package com.by.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("add.......");
}
}
(2)业务层实现类
package com.by.service;
import com.by.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public void addUser() {
userDao.addUser();
}
}
(3)模拟表现层
package com.by.servlet;
import com.by.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = ac.getBean("userServiceImpl", UserService.class);
userService.addUser();
}
}
(4)通知类
/*
* Copyright (c) 2020, 2024, webrx.cn All rights reserved.
*
*/
package com.by.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component//将这个类交给spring管理
@Aspect//把当前类声明为切面类
public class MyAdvice {
//1.前置通知
@Before("execution(* com.by.service.*.*(..))")
public void before(){
System.out.println("前置通知");
}
//2.最终通知
@After("execution(* com.by.service.*.*(..))")
public void after(){
System.out.println("我是最终通知");
}
//3.异常通知
@AfterThrowing("execution(* com.by.service.*.*(..))")
public void afterThrowing(){
System.out.println("我是异常通知");
}
//4. 环绕通知
@Around("execution(* com.by.service.*.*(..))")
public void around(ProceedingJoinPoint joinPoint){
try {
System.out.println("我是前置环绕通知");
joinPoint.proceed();
System.out.println("我是后置环绕通知");
}catch (Throwable throwable){
throwable.printStackTrace();
}
}
//5.后置通知
@AfterReturning("execution(* com.by.service.*.*(..))")
public void afterReturning(){
System.out.println("我是后置通知");
}
}
六、运行结果
运行顺序受通知位置顺序的影响