- 经典的基于代理的AOP+aop:config的标签实现
- 通过注解实现(AspectJ注解)
- 自定义切面实现aop
1、第一种经典方法使用
a、5大增强类方法
- Before(前) org.apringframework.aop.MethodBeforeAdvice
- After-returning(返回后) org.springframework.aop.AfterReturningAdvice
- After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
- Arround(周围) org.aopalliance.intercept.MethodInterceptor
- Introduction(引入) org.springframework.aop.IntroductionInterceptor
- 前置通知实现
package com.lin.cn.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* @Author Lin_Home
* @Date 2020/11/8 20:46
* @Version 1.0
*/
/*前置通知*/
public class BeforeLog implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(method.getName()+"----"+args.getClass().getName());
}
}
- 后置通知实现
package com.lin.cn.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
/**
* @Author Lin_Home
* @Date 2020/11/8 20:52
* @Version 1.0
*/
/*后置增强*/
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置通知"+ target.getClass().getName()+"---" +method.getName()+"---"+returnValue);
}
}
- 环绕通知
package com.lin.cn.log;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* @Author Lin_Home
* @Date 2020/11/8 20:59
* @Version 1.0
*/
public class AroundLog implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕开始中");
Object proceed = invocation.proceed();
return proceed;
}
}
- 引入通知
package com.lin.cn.log;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;
/**
* @Author Lin_Home
* @Date 2020/11/8 21:02
* @Version 1.0
*/
public class IntroductionLog implements IntroductionInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("引入的使用");
return invocation.proceed();
}
@Override
public boolean implementsInterface(Class<?> intf) {
return false;
}
}
- 编写一个接口
package com.lin.cn.dao;
/**
* @Author Lin_Home
* @Date 2020/11/8 20:36
* @Version 1.0
*/
public interface EmpDao {
void add();
void delete();
void update();
void select();
}
- 接口的实现类
package com.lin.cn.dao.impl;
import com.lin.cn.dao.EmpDao;
/**
* @Author Lin_Home
* @Date 2020/11/8 20:37
* @Version 1.0
*/
public class EmpDaoImpl implements EmpDao {
@Override
public void add() {
System.out.println("添加功能");
}
@Override
public void delete() {
System.out.println("删除功能");
}
@Override
public void update() {
System.out.println("修改功能");
}
@Override
public void select() {
System.out.println("查询功能");
}
}
- 编写一个测试类
package com.lin.cn.test;
import com.lin.cn.dao.EmpDao;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author Lin_Home
* @Date 2020/11/8 21:16
* @Version 1.0
*/
public class MainTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
EmpDao empDao = (EmpDao) context.getBean("empDao");
empDao.add();
}
}
- 配置文件的编写
<?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="empDao" class="com.lin.cn.dao.impl.EmpDaoImpl"/>
<bean id="beforeLog" class="com.lin.cn.log.BeforeLog"/>
<bean id="afterLog" class="com.lin.cn.log.AfterLog"/>
<bean id="introductionLog" class="com.lin.cn.log.IntroductionLog"/>
<bean id="aroundLog" class="com.lin.cn.log.AroundLog"/>
<aop:config>
<!--切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.lin.cn.dao.impl.EmpDaoImpl.* (..))"/>
<!--增强类-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="introductionLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="aroundLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
2、第二种实现自定义切面
- 自定义切面
package com.lin.cn.log;
/**
* @Author Lin_Home
* @Date 2020/11/8 22:16
* @Version 1.0
*/
/*自定义切面*/
public class Log {
public void beforeLog(){
System.out.println("实现了前置通知");
}
public void afterLog(){
System.out.println("实现了后置通知");
}
public void aroundLog(){
System.out.println("实现了环绕通知");
}
}
- 自定义的xml 文件配置
<!--实现自定义切面-->
<bean id="log" class="com.lin.cn.log.Log"/>
<aop:config>
<aop:aspect ref="log">
<!--引入切点-->
<aop:pointcut id="pointcut" expression="execution(* com.lin.cn.dao.impl.EmpDaoImpl.* (..))"/>
<aop:before method="beforeLog" pointcut-ref="pointcut"/>
<aop:after method="afterLog" pointcut-ref="pointcut"/>
<aop:around method="aroundLog" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
第三种 注解实现aop
编写一个注解类
package com.lin.cn.log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @Author Lin_Home
* @Date 2020/11/8 22:33
* @Version 1.0
*/
/*用注解方式实现*/
@Aspect
public class AnnotationLog {
@Before("execution(* com.lin.cn.dao.impl.EmpDaoImpl.* (..))")
public void beforeLog(){
System.out.println("实现了前置通知");
}
@After("execution(* com.lin.cn.dao.impl.EmpDaoImpl.* (..))")
public void afterLog(){
System.out.println("实现了后置通知");
}
@Around("execution(* com.lin.cn.dao.impl.EmpDaoImpl.* (..))")
public void aroundLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("实现了环绕通知前");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("实现了环绕通知后");
}
}
- 配置文件编写
<!--方法三注解实现-->
<bean id="annotationPointCut" class="com.lin.cn.log.AnnotationLog"/>
<aop:aspectj-autoproxy/>
<!--这个是使用cglib的方法实现-->
<!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->