首页 > 其他分享 >【spring框架】AOP的Annotation实现(上)

【spring框架】AOP的Annotation实现(上)

时间:2023-04-03 16:31:57浏览次数:40  
标签:Spring spring AOP springframework Annotation 切面 import org AspectJ


使用Annotation来实现AOP的动态代理:
@AspectJ支持
@AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。@AspectJ样式在AspectJ 5发布的AspectJ project部分中被引入。Spring 2.0使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器(weaver)。 

使用AspectJ的编译器或者织入器的话就可以使用完整的AspectJ语言,我们将在第 6.8 节 “在Spring应用中使用AspectJ”中讨论这个问题。

6.2.1. 启用@AspectJ支持
为了在Spring配置中使用@AspectJ切面,你首先必须启用Spring对@AspectJ切面配置的支持,并确保自动代理(autoproxying)的bean是否能被这些切面通知。自动代理是指Spring会判断一个bean是否使用了一个或多个切面通知,并据此自动生成相应的代理以拦截其方法调用,并且确保通知在需要时执行。 

通过在你的Spring的配置中引入下列元素来启用Spring对@AspectJ的支持:

<aop:aspectj-autoproxy/>

需要的jar包:aspectjrt.jar、aspectjweaver.jar

需要加新的命名空间:

xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"


beans.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
               
  <context:annotation-config/>
  <context:component-scan base-package="cn.edu.hpu"/>
  <!-- 可以采用使用aspectj注解的方式产生aop -->
  <aop:aspectj-autoproxy/><!-- 自动产生代理,原理是aspectj,它是一个专门用来生成代理的框架 -->
</beans>


实验:


需要加在前面的代理类LogInterceptor:


package cn.edu.hpu.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogInterceptor {
	//在方法执行之前先执行这个方法
	//execution是织入点语法
	@Before("execution(public void cn.edu.hpu.dao.Impl.UserDaoImpl.save(cn.edu.hpu.model.User))")
	public void before(){
		System.out.println("method start");
	} 
}


测试:

package cn.edu.hpu.service;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.edu.hpu.dao.UserDao;
import cn.edu.hpu.model.User;

public class UserServiceTest {
	
	@Test
	public void testAdd() throws Exception{
		ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
		
		UserService userService=(UserService)ctx.getBean("userService");
		User u=new User();
		u.setUsername("u1");
		u.setPassword("p1");
		userService.add(u);
		ctx.destroy();
	}
}

结果:


method start


add success!!



原理:


首先spring会通过


<context:annotation-config/>
<context:component-scan base-package="cn.edu.hpu"/>

去按照注解@Component注解去找相应的bean,在找LogInterceptor的时候,它发现这个类还是一个@Aspect,也就是说这个是个切面逻辑,可以把它切到其它的方法上面去,那么它怎么往里切呢?他发现了你用@Before定义了一下,在这个execution指定的方法执行之前(execution方法、属性、类)去执行下面定义的方法。




execution可以指定在任何方法上,UserDaoImpl自己的业务逻辑不会受任何影响,它甚至不知道有新的逻辑切入进来了,这就保证了UserDaoImpl业务逻辑的纯洁性。




下面介绍一些专业术语:


关于Spring的AOP的一些专业术语:


1.JoinPoint:


连接点、切入点


就是说在哪些点上把切面逻辑加进去(比如在save方法之前)



2.PointCut:


切入点的集合


我们可以一下定好多切入点


例如:在com.xyz.someapp.service任何类的任何方法切入


@PointCut("execution(* com.xyz.someapp.service.*.*(...))")


public voidbussinessService(){}



3.Aspect(切面):


前面我们写的LogInterceptor切面类里面有好多方法加到不同的被代理的对


象上面去,这就是那个切面。也就是加@Aspect注解的类。



4.Advice:


在加入的那个点上的"建议",与Aspect意思有些重合。


可以这样理解,Aspect是个"面",而Advice是那个"面"的逻辑


就是在你要代理的方法上加"@Before或@After等逻辑"



5.Target:


被代理对象


把我们的业务逻辑"织入"到哪个对象上面去



6.Weave:


织入。


和织布机一样,横排的织完,竖排的再去织,这时候就像业务逻辑切进去一样,被织入进去了。

 

标签:Spring,spring,AOP,springframework,Annotation,切面,import,org,AspectJ
From: https://blog.51cto.com/u_16012040/6166750

相关文章

  • spring源码各个版本中的两个字符串比较的变更,值得学习
    判断一个字符串是否空串:1、Spring旧版本使用equals,新版本使用isEmpty()方法;查找String的源码发现isEmpty的底层使用this.value.length==0进行判断。粗略分析:equals在进行比较时耗时约0.1秒,==无耗时。 ......
  • 24-springboot-thymeleaf的表达式
    1.添加热部署,为了测试不用频繁重启<!--热部署插件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><!--防止将该依赖传递到其他模块中--></depen......
  • 25-springboot-thymeleaf的常见属性
    th:action<formid="login"th:action="@{/login}">......</form>th:method<formid="login"th:action="@{/login}"th:method="post">......</form>th:href<a class="login"......
  • MyBatis-Spring包自动扫描MyBatis Mapper接口并将其注册为Spring Bean
    学习spring整合mybatis时,写SQL语句的Mapper接口明明没有任何被spring接管的痕迹(前面没有注解)但在serviceimpl类中却可以被自动装载。 BookDao.java(mapper接口类):packagecom.itheima.dao;importcom.itheima.domain.Book;importorg.apache.ibatis.annotations.Delete;imp......
  • 22-springboot应用监控-actuator
    可以做成页面监控(springboot-admin),而不是json的格式,看起来会更方便。在生产环境中,有时可能需要监控服务的可用性,spring-boot的actuator就是提供了对应用的配置查看、健康检查、相关功能统计等,可以通过HTTP,JMX来访问这些监控功能;(端点)如何使用该功能呢?1、在项目的Maven中添......
  • 加载spring配置的两个方法AnnotationConfigApplicationContext()和getRootConfigClass
    在Spring中,AnnotationConfigApplicationContext类和AbstractAnnotationConfigDispatcherServletInitializer类中的getRootConfigClasses()方法都是用来加载Spring配置类,并创建Spring容器的。因此,它们的作用是相似的,都是用来配置Spring容器的。但是,它们的使用场景和......
  • SpringCloud大文件上传解决方案支持分片断点上传
    ​IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头。 一. 两个必要响应头Accept-Ranges、ETag        客户端每次提交下载请求时,服务端都要添加这两个响应头,以保证客户端和服务端将此下载识别为可以断点续传......
  • SpringMVC大文件上传解决方案支持分片断点上传
    ​ 以ASP.NETCoreWebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API,包括文件的上传和下载。 准备文件上传的API #region 文件上传  可以带参数        [HttpPost("upload")]        publicJsonResultuploadProject(I......
  • 【Spring】AOP
    添加Maven依赖:<!--aspectj包的依赖--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.1</version></dependency><!--aspectjr......
  • Spring源码复习
    Bean的生命周期 ApplicationContextCentralinterfacetoprovideconfigurationforanapplication.*Thisisread-onlywhiletheapplicationisrunning,butmaybe*reloadediftheimplementationsupportsthis.**<p>AnApplicationContextprovides:*<ul......