欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

02-面向切面AOP

程序员文章站 2022-07-12 14:11:17
...

Spring-02面向切面AOP
欢迎大家访问学习:
Spring学习:https://how2j.cn/k/spring/spring-ioc-di/87.html?p=36286
02-面向切面AOP

一、介绍

1、面向切面编程,

2、AOP让一组类共享相同的方法。

3、Spring支持AspectJ的注解式切面编程。

二、需求

演示模拟记录日志的操作系统。基于注解拦截和方法规则拦截两种方式。

三、演示

添加pom文件(基于Spirng01之后的添加,可参考前面文章Spring01)

<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>4.1.6.RELEASE</version>
		</dependency>
		<!-- aspectj支持 -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.8.6</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.5</version>
		</dependency>

1、基于注解拦截

a.编写可以用于拦截规则的注解
package com.eleven.aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 拦截规则的注解
 * 
 * @author sywangu
 *
 */
@Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
@Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
@Documented // 该注解表示是否应当被包含在JavaDoc文档中
public @interface Action {

	String name();
}

b.编写并使用注解的被拦截类
package com.eleven.aop;

import org.springframework.stereotype.Service;

@Service
public class DemoAnnotationService {
	@Action(name = "使用注解式拦截的add")
	public void add() {}

}

c.编写切面
package com.eleven.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect // 通过该注解声明一个切面
@Component // 该注解表示让这个切面成为Spring管理的一个Bean
public class LogAspect {
	// 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
	@Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
	public void annotationPointCut() {}
	
	@After("annotationPointCut()") // 使用@PointCut定义的切点
	public void after(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();	// 方法签名
		Method method = signature.getMethod();	// 获得签名里面的方法
		Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
		System.out.println("注解式拦截:" + action.name());
	}

}

d.配置类
package com.eleven.aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration // 声明当前类是一个配置类
@ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
@EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
public class AopConfig {

}

e.运行输出
package com.eleven.aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
		DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
		
		demoAnnotationService.add();
		
		context.close();
	}

}

02-面向切面AOP

2、基于方法规则拦截

可直接在当前项目中编写,下面和上面的是一起的,继续写就行。

a.编写并使用方法规则的被拦截类
package com.eleven.aop;

import org.springframework.stereotype.Service;

@Service // 声明当前类是Spring管理的一个Bean
public class DemoMethodService {
	public void add() {}

}

b.编写切面
// 基于方法规则的被拦截类
	@Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
	public void before(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
		Method method = signature.getMethod();
		System.out.println("方法规则拦截:" + method.getName());

	}
c.运行输出

在Main里面。

// 基于方法规则的拦截
		DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
		demoMethodService.add();

02-面向切面AOP

3.完整代码(以上两个合在一起)

a.Action(拦截规则的注解类)
package com.eleven.aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 拦截规则的注解
 * 
 * @author sywangu
 *
 */
@Target(ElementType.METHOD) // 表示注解的作用目标,用例修饰字段、方法和类
@Retention(RetentionPolicy.RUNTIME) // 表示注解的声明周期
@Documented // 该注解表示是否应当被包含在JavaDoc文档中
public @interface Action {

	String name();
}

b.AopConfig(配置类)
package com.eleven.aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration // 声明当前类是一个配置类
@ComponentScan("com.eleven.aop") // 自动扫描包下面所有的注解
@EnableAspectJAutoProxy // 该注解表示开启Spring对AspectJ的支持
public class AopConfig {

}

c.DemoAnnotationService(注解的被拦截类)
package com.eleven.aop;

import org.springframework.stereotype.Service;

@Service
public class DemoAnnotationService {
	@Action(name = "使用注解式拦截的add")
	public void add() {}

}

d.DemoMethodService(方法规则的被拦截类)
package com.eleven.aop;

import org.springframework.stereotype.Service;

@Service // 声明当前类是Spring管理的一个Bean
public class DemoMethodService {
	public void add() {}

}

e.LogAspect(切面)
package com.eleven.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect // 通过该注解声明一个切面
@Component // 该注解表示让这个切面成为Spring管理的一个Bean
public class LogAspect {
	// 为了使切点能够多次调用,可以使用PointCue定义一个拦截规则
	@Pointcut("@annotation(com.eleven.aop.Action)") // 通过该注解声明切点
	public void annotationPointCut() {
	}

	// 基于注解的被拦截方式
	@After("annotationPointCut()") // 使用@PointCut定义的切点
	public void after(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
		Method method = signature.getMethod(); // 获得签名里面的方法
		Action action = method.getAnnotation(Action.class); // // 通过反射可以获得注解上的属性,然后做日志记录操作
		System.out.println("注解式拦截:" + action.name());
	}

	// 基于方法规则的被拦截类
	@Before("execution(* com.eleven.aop.DemoMethodService.*(..))")
	public void before(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名
		Method method = signature.getMethod();
		System.out.println("方法规则拦截:" + method.getName());

	}
}

f.Main(运行输出)
package com.eleven.aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
		// 基于注解的方式
		DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
		demoAnnotationService.add();

		// 基于方法规则的拦截
		DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
		demoMethodService.add();

		context.close();
	}

}

02-面向切面AOP

相关标签: Spring