记录跟着狂神学Spring的历程(第20集)~
1. 导包
导入aop织入包
xml
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>

2. 方式一:xml配置文件+Spring接口
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 id="userService" class="com.pojo.UserServiceImpl"/>
<bean id="log" class="com.pojo.Log"/>
<aop:config>
<!-- 切入点:要在哪里切入 -->
<!-- 方式1 execution 匹配指定类的所有方法 -->
<aop:pointcut id="pointcut" expression="execution(* com.pojo.service.UserServiceImpl.*.*(..))"/>
<!-- 方式2:用within简化(等价,更简洁) -->
<aop:pointcut id="pointcut" expression="within(com.pojo.service.UserServiceImpl.*)"/>
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
</aop:config>
</beans>
- expression: 就是 AOP 的筛选规则------ 告诉 Spring 要把增强逻辑(比如前置日志)织入到哪些方法上。
- execution语法:execution( [修饰符] 返回值类型 包名.类名.方法名(参数类型) [异常类型] )
然后写一个Log类,实现aop里的接口,比如MethodBeforeAdvice、AfterReturningAdvice
java
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)context.getBean("userService");
userService.add();
}
会输出日志。
3.方式二:自定义切面
定义一个日志类(切面)
Java
public class Diy{
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
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中 -->
<bean id="diy" class="com.pojo.Diy"/>
<aop:config>
<!-- 设置切面 ref代表要引用的类 -->
<aop:aspect ref="diy">
<!-- 切入点 匹配指定类的所有方法 -->
<aop:pointcut id="pointcut" expresssion="execution(* com.pojo.service.UserServiceImpl.*.*(..))"/>
<!-- 通知 -->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:before method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
<aop:before method="before" pointcut-ref="point"/>:切入点前通知,这里的before方法是自定义的类Diy里的before方法。
4. 注解版
Java
@Aspect
public class MyAspect{
@Before("execution=(* com.pojo.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("方法执行前");
}
@After("execution=(* com.pojo.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("方法执行后");
}
// 环绕
@After("execution=(* com.pojo.service.UserServiceImpl.*(..))")
public void around(){
System.out.println("方法环绕");
}
}
@Aspect: 标注这个类是一个切面。
@Before: 等价于
<aop:pointcut id="pointcut" expresssion="execution(* com.pojo.service.UserServiceImpl.*.*(..))"/>
<aop:before method="before" pointcut-ref="pointcut"/>
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">
<!-- 启用AOP注解支持 -->
<aop:aspectj-autoproxy/>
<!-- 定义一个切面 -->
<bean id="myAspect" class="com.pojo.MyAspect"/>
<!-- 定义一个被通知的对象 -->
<bean id="myService" class="com.example.MyService"/>
</beans>