文章目录

  • 前言
  • 一、pom文件
  • 二、配置文件形式
  • 2.1 target 目标对象
  • 2.2 Advice 增强对象
  • 2.3 target 目标函数接口
  • 2.4 applicationContext.xml
  • 2.4.1 切点表达式的写法
  • 2.4.2 通知的类型
  • 2.5 aop测试
  • 三、注解形式
  • 3.1 target 目标对象
  • 3.2 Advice增强对象
  • 3.3 target 目标对象接口
  • 3.4 applicationContext-anno.xml
  • 3.5 anno测试



前言

springAop+aspectJ可以实现:
1 配置文件开发
2 注解开发

一、pom文件

  1. spring context 内部包含aop相关
  2. aspectjweaver 使用到内部的注解
  3. 剩下的主要用于测试使用
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

二、配置文件形式

spring二次开发实例_后端

2.1 target 目标对象

package com.mytest.aop;

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("method running");
    }
}

2.2 Advice 增强对象

package com.mytest.aop.impl;

public class Advice {
    public void preAdv(){
        System.out.println("前置增强。。。");
    }
    public void postAdv(){
        System.out.println("后置增强。。。");
    }
}

2.3 target 目标函数接口

package com.mytest.aop;

public interface TargetInterface {
    public void method();
}

2.4 applicationContext.xml

要配置切面

  1. 目标对象
  2. 增强对象
  3. 将增强对象作为切面,配置切点和通知

该配置:给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
                            ">
<!--    配置切面 = 切点+通知-->
<!--    配置 包含切点的目标对象-->
    <bean id="target" class="com.mytest.aop.Target"></bean>
<!--    配置 包含通知的增强对象-->
    <bean id="advice" class="com.mytest.aop.impl.Advice"></bean>
<!--    配置切面-->
    <aop:config>
        <aop:aspect ref="advice">
<!--            配置具体方法 切点+通知-->
<!--            <aop:before method="preAdv" pointcut="execution(public void com.mytest.aop.Target.method())"/>-->
            <aop:before method="preAdv" pointcut="execution(* com.mytest.aop.*.*(..))"/>
        </aop:aspect>
    </aop:config>
</beans>

2.4.1 切点表达式的写法

语法

pointcut="execution([修饰符] 返回值类型 包名.类名.方法名(参数))"
  • 访问修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号* 代表任意
  • 包名与类名之间一个点 . 代表当前包下的类,两个点 … 表示当前包及其子包下的类
  • 参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表

所以

execution(* com.mytest.aop.*.*(..))

表示任意返回值类型,在com.mytest.aop包下的任意方法及其子类,都要进行增强。

2.4.2 通知的类型

语法

<aop:通知类型 method=“切面方法” pointcut=“切点表达式"></aop:通知类型>

类型如下

名称

标签

说明

前置通知

aop:before

指定增强的方法在切点方法前执行

后置通知

aop:after-returning

指定增强的方法在切点方法后执行

环绕通知

aop:around

指定增强的方法在切点方法前和后都执行

异常抛出通知

aop:throwing

指定增强的方法在出现异常时执行

最终通知

aop:after

无论增强方式执行是否有异常都会执行

2.5 aop测试

package com.mytest.aop.test;

import com.mytest.aop.TargetInterface;
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;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestAop {
    @Autowired
    private TargetInterface target;

    @Test
    public void testTarget(){
        target.method();
    }
}

三、注解形式

3.1 target 目标对象

增加了@Component(“target”)

package com.mytest.anno;

import org.springframework.stereotype.Component;

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("method running");
    }
}

3.2 Advice增强对象

使用到
@Aspect 表明是一个切面类
@Before 内写切点的表达式

package com.mytest.anno.impl;

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

@Component("annoAdvice")
@Aspect
public class Advice {
    @Before("execution(* com.mytest.anno.*.*(..))")
    public void preAdv(){
        System.out.println("前置增强。。。");
    }

    public void postAdv(){
        System.out.println("后置增强。。。");
    }
}

3.3 target 目标对象接口

package com.mytest.anno;

public interface TargetInterface {
    public void method();
}

3.4 applicationContext-anno.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"
       xmlns:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--    组件扫描-->
    <context:component-scan base-package="com.mytest.anno"></context:component-scan>
<!--    自动代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

3.5 anno测试

package com.mytest.aop.test;


import com.mytest.anno.TargetInterface;
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;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-anno.xml")
public class TestAnno {
    @Autowired
    private TargetInterface target;

    @Test
    public void testTarget(){
        target.method();
    }
}

该处使用的url网络请求的数据。