转载

Spring Aspectj

文档

https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/xsd-configuration.html

Maven

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.ming</groupId>
  <artifactId>mingming111</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>mingming111 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.1.7.RELEASE</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>jsr250-api</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>RELEASE</version>
      <scope>test</scope>
    </dependency>
    <!-- AOP -->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <!-- aspectj -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.1.8.RELEASE</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>mingming111</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

启用注解

<?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 definitions here -->
	<!-- 开启aspectj注解 开发-->
	<aop:aspectj-autoproxy/>
</beans>

通知类型

前置通知 beforeadvice 使用权限校验

后置通知 日志记录,,使用后置通知

环绕通知 目标方法执行之前,之后执行的操作 可以阻止执行目标方法 进行事物管理,,使用环绕通知。

最终通知 final

引介通知

execution函数 访问修饰符 返回类型 方法名 参数 异常

匹配类的public方法

匹配所有类的public方法

execution(public * *(..))

匹配public修饰符 返回类型为任意 方法名为任意 参数为任意

匹配包下的所有类方法

execution(* com.ming.dao.*(..))

匹配包下的所有类的方法 不包含子包

返回类型为任意,方法为com.ming.dao下的第一级的方法

子包 子包下的所有类

execution(* com.ming.dao.. *(..))

匹配指定类下的所有方法

execution(* com.ming.dao.*(..))

匹配实现特定接口的所有方法

execution(* com.ming.dao+.*(..))

+代表实现了该接口的所有方法

匹配所有save开头的方法

execution(* save*(..))

任意的返回值 save开头

入门案例

package com.ming;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 切面类
 * @author ming
 */
@Aspect
public class MyAspectDao {
    @Before(value="execution(* com.ming.ProductDao.save(..))")
    public void before(){
        System.out.println("前置通知");
    }


}
package com.ming;

public class ProductDao {
    public void save(){
        System.out.println("保存");
    }

    public void update(){
        System.out.println("update");
    }

    public void delete(){
        System.out.println("delete");
    }

    public void findOne(){
        System.out.println("findOne");
    }

    public void findAll(){
        System.out.println("findAll");
    }
}
<?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 definitions here -->
	<!-- 开启aspectj注解 开发-->
	<aop:aspectj-autoproxy/>
	
	<!-- 目标类 -->
	<bean id="productDao" class="com.ming.ProductDao"/>
	
	<!-- 定义切面 -->
	<bean class="com.ming.MyAspectDao"/>
</beans>
package com.ming;

import org.aspectj.lang.annotation.Aspect;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ProductDaoTest {
    @Autowired
    private ProductDao productDao;

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void save() {
        productDao.save();
    }

    @Test
    public void update() {
        productDao.update();
    }

    @Test
    public void delete() {
        productDao.delete();
    }

    @Test
    public void findOne() {
        productDao.findOne();
    }

    @Test
    public void findAll() {
        productDao.findAll();
    }
}

com.ming.ProductDao.save

进行拦截,添加前置通知

前置通知

获得切点信息

package com.ming;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 切面类
 * @author ming
 */
@Aspect
public class MyAspectDao {
    @Before(value="execution(* com.ming.ProductDao.save(..))")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知" +  joinPoint);
    }


}

后置通知

在执行之后执行通知

package com.ming;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 切面类
 * @author ming
 */
@Aspect
public class MyAspectDao {
    @Before(value="execution(* com.ming.ProductDao.save(..))")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知" +  joinPoint);
    }

    @AfterReturning(value = "execution(* com.ming.ProductDao.save(..))", returning = "res")
    public void afterReturing(Object res){
        System.out.println("后置通知" + res);
    }

}

环绕通知

使用@Around注解

如果不调用,直接被拦截

@Around(value="execution(* com.ming.ProductDao.save(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("环绕前 通知");
        Object obj = joinPoint.proceed();
        System.out.println("环绕否通知");
        return obj;
    }

异常抛出

设置@AfterThrowing 设置发生异常的参数

After 最终通知

使用@After注解

最终通知在后置通知之前

Pointcut

package com.ming;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * 切面类
 * @author ming
 */
@Aspect
public class MyAspectDao {
    @Before(value="myPointcutj()")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知" +  joinPoint);
    }

    @AfterReturning(value = "execution(* com.ming.ProductDao.save(..))", returning = "res")
    public void afterReturing(Object res){
        System.out.println("后置通知" + res);
    }


    @Around(value="execution(* com.ming.ProductDao.save(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("环绕前 通知");
        Object obj = joinPoint.proceed();
        System.out.println("环绕否通知");
        return obj;
    }

    @After(value="execution(* com.ming.ProductDao.save(..))")
    public void after(){
        System.out.println("最终通知");
    }

    @Pointcut(value="execution(* com.ming.ProductDao.save(..))")
    private void myPointcutj(){

    }
}

基于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 definitions here -->
	<!-- 配置目标类 -->
	<bean id="customerDao" class="com.ming.CustomerDaoImpl"/>
	
	<!-- 配置切面类 -->
	<bean class="com.ming.MyAspectXml" id="myAspectXml"/>
	<!-- AOP配置 -->
	<aop:config>
		<!-- 配置切入点 -->
		<aop:pointcut id="pointcuti" expression="execution(* com.ming.CustomerDao.save(..))"/>
		<!-- 切面 -->
		<aop:aspect ref="myAspectXml">
			<!-- 配置前置通知 -->
			<aop:before method="before" pointcut-ref="pointcuti"/>
		</aop:aspect>

	</aop:config>
</beans>
原文  https://www.iming.info/spring-2/
正文到此结束
Loading...