注解与 xml 实现aop哪种好_Spring 从入门到入土——AOP 就这么简单!| 原力计划

d1dc3deb-2f13-eb11-8da9-e4434bdf6706.png

作者| 冢狐

责编 | 夕颜出品 | CSDN博客

d3dc3deb-2f13-eb11-8da9-e4434bdf6706.png

什么是AOP?

面向切面编程(Aspect Oriented Programming),通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分的耦合度降低,提高程序的可重用性,同时提高了开发效率。

d5dc3deb-2f13-eb11-8da9-e4434bdf6706.png

AOP在Spring中的作用

  • 提供声明式事务;允许用户自定义切面

核心名词

  • 横切关注点:横跨应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的地方,就是横切关注点,如:日志、安全、缓存、事务
  • 切面:横切关注点被模块化的特性对象,即:它是一个类
  • 通知:切面必须要完成的工作。即它是类中的一个方法
  • 目标:被通知对象
  • 代理:向目标对象应用通知以后创建的对象。
  • 切入点:切面通知执行的“地点的定义
  • 连接点:与切入点匹配的执行点

Spring中支持的五种类型的Advice

dadc3deb-2f13-eb11-8da9-e4434bdf6706.png

即Aop在不改变原有代码的情况下,去增加新的功能。

dfdc3deb-2f13-eb11-8da9-e4434bdf6706.png

使用Spring实现Aop

使用AOP,需要导入一个依赖包

org.aspectj aspectjweaver 1.9.4

第一种方式——通过Spring API实现

业务接口和实现类

public interface UserService { public void add; public void delete; public void update; public void search;}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 search { System.out.println("查询用户"); }}

增强类

  • 前置增强
public class Log implements MethodBeforeAdvice { //method : 要执行的目标对象的方法 //objects : 被调用的方法的参数 //Object : 目标对象 @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println( o.getClass.getName + "的" + method.getName + "方法被执行了"); }}
  • 后置增强
public class AfterLog implements AfterReturningAdvice { //returnValue 返回值 //method被调用的方法 //args 被调用的方法的对象的参数 //target 被调用的目标对象 @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了" + target.getClass.getName +"的"+method.getName+"方法," +"返回值:"+returnValue); }}

去Spring的文件中注册,并实现aop切入实现

<?xml version="1.0" encoding="UTF-8"?>

测试

public class MyTest { @Test public void test{ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.search; }}

Aop的重要性:很重要,一定要理解其中的思路

Spring的Aop就是将公共的业务(日志、安全)和领域业务结合起来,当执行领域业务时,将会把公共业务加起来,实现公共业务的重复利用,领域业务更加纯粹,程序员只需要专注领域业务。

其本质还是动态代理

第二种方式:自定义类来实现Aop

目标业务不变依旧是userServiceImpl

切入类

public class DiyPointcut { public void before{ System.out.println("---------方法执行前---------"); } public void after{ System.out.println("---------方法执行后---------"); }}

去spring中配置

测试

public class MyTest { @Test public void test{ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add; }}

第三种方式——使用注解

注解实现的增强类

package com.zhonghu.config;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;@Aspectpublic class AnnotationPointcut { @Before("execution(* com.zhonghu.service.UserServiceImpl.*(..))") public void before{ System.out.println("---------方法执行前---------"); } @After("execution(* com.zhonghu.service.UserServiceImpl.*(..))") public void after{ System.out.println("---------方法执行后---------"); } @Around("execution(* com.zhonghu.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); System.out.println("签名:"+jp.getSignature); //执行目标方法proceed Object proceed = jp.proceed; System.out.println("环绕后"); System.out.println(proceed); }}

在spring配置文件中,注册bean,并增加支持注解的配置

aop:aspectj-autoproxy:说明

  • 通过aop创建的命名空间的声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被隐藏起来了
  • 有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理

进行自动代理的创建工作,但具体实现的细节已经被隐藏起来了。

  • 有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理

版权声明:本文为CSDN博主「冢狐」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/issunmingzhi/java/article/details/106051063

e1dc3deb-2f13-eb11-8da9-e4434bdf6706.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值