Spring实现AOP的三种方式,你掌握了几种?

Stephen

共 5112字,需浏览 11分钟

 ·

2021-09-03 23:46

①导入Jar


<dependencies>        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjweaver</artifactId>            <version>1.9.4</version>        </dependency>    </dependencies>


②配置文件开启aop文件头引用约束


<?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">
</beans>


③抽象接口


public interface UserService {    void add();    void delete();    void update();    void selete();}


④实现类


public class UserServiceImpl implements UserService {    @Override    public void add() {        System.out.println("增加用户");    }
@Override public void delete() { System.out.println("删除用户"); }
@Override public void update() { System.out.println("更新用户"); }
@Override public void selete() { System.out.println("查询用户"); }}



一、通过 Spring API 实现

①添加前置后置方法


public class AopBeforeConfigLog implements MethodBeforeAdvice {
/** * method : 要执行的目标对象的方法 * args : 被调用的方法的参数 * target : 目标对象 */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass()+"===="+method.getName()+"被执行了"); }}
public class AopAfterConfigLog implements AfterReturningAdvice {
/** * method : 要执行的目标对象的方法 * args : 被调用的方法的参数 * result : 返回值 * target : 被调用的目标对象 */
@Override public void afterReturning(Object result, Method method, Object[] args, Object target){ System.out.println(target.getClass()+"===="+method.getName()+"被执行了"+"===返回值"+result); }}


②beans.xml


    <!--注册bean-->    <bean id="userService" class="service.UserServiceImpl"/>    <bean id="afterLog" class="aoptest.AopAfterConfigLog"/>    <bean id="beforeAop" class="aoptest.AopBeforeConfigLog"/>
<aop:config> <!--切入点 expression:表达式匹配要执行的方法--> <aop:pointcut id="cut" expression="execution(* service.UserServiceImpl.*(..))"/>
<!--执行环绕; advice-ref执行方法 . pointcut-ref切入点--> <aop:advisor advice-ref="afterLog" pointcut-ref="cut"/> <aop:advisor advice-ref="beforeAop" pointcut-ref="cut"/> </aop:config>
③测试类
public class TestAop {    public static void main(String[] args) {        ApplicationContext Context = new ClassPathXmlApplicationContext("ContextAplication.xml");        UserService userService = (UserService) Context.getBean("userService");        userService.add();        userService.selete();        userService.update();        userService.delete();    }}
④执行结果


⑤总结:

  • 切面:横切的点

  • 通知:切面完成的工作,其实就是一个方法

  • 目标:被通知的对象

  • expression="execution(* service.UserServiceImpl.*(..))" 这是一套固定的公式 *代表所有 这句话的意思就是service.UserServiceImpl下的所有方法都被切面了!

二、自定义类来实现

①自定义被切入类


/** 自定义类* */public class MyDIYAopCut {    public void before(){        System.out.println("方法执行前前前前前前前前前前");    }    public void after(){        System.out.println("方法执行后后后后后后后后后后");    }}


②beans.xml


    <!--注册bean-->    <bean id="userService" class="service.UserServiceImpl"/>    <bean id="Mydiycut" class="diyaop.MyDIYAopCut"/>
<aop:config> <!--这里的ref指定被 切入 的类是哪一个--> <aop:aspect ref="Mydiycut"> <!--切入点--> <aop:pointcut id="cut" expression="execution(* service.UserServiceImpl.*(..))"/>
<!--切入点之前执行,这里的方法名即是我们自定义类中的方法名--> <aop:before method="before" pointcut-ref="cut"/> <!--切入点之后执行,这里的方法名即是我们自定义类中的方法名--> <aop:before method="after" pointcut-ref="cut"/> </aop:aspect> </aop:config>


③测试类不变,执行结果

④总结:

  • 测试类的方法即是xml中method的方法名

  • 其他见xml中的注释!

三、使用注解实现

①自定义增强注解实现类


@Aspectpublic class MyAnnotationAopCut {    @Before("execution(* service.UserServiceImpl.*(..))")    public void before(){        System.out.println("方法执行前");    }    @After("execution(* service.UserServiceImpl.*(..))")    public void after(){        System.out.println("方法执行后");    }    @Around("execution(* service.UserServiceImpl.*(..))")    public void around(ProceedingJoinPoint point) throws Throwable {        System.out.println("环绕前=="+point.getSignature());        //执行        Object proceed = point.proceed();        System.out.println("环绕后=="+point.getSignature());    }}


②xml


    <!--注册bean-->    <bean id="userService" class="service.UserServiceImpl"/>    <bean id="myAnnotationAopCut" class="diyaop.MyAnnotationAopCut"/>    <!--声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面-->    <aop:aspectj-autoproxy proxy-target-class="false"/>


③测试类一致,执行结果



--  end  --


关注 Stephen,一起学习,一起成长。

浏览 23
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报