增加spel配合注解示例
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.wyl</groupId>
|
||||
<artifactId>spring-boot-common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-common</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.wyl.spring.boot.common;
|
||||
|
||||
import com.wyl.spring.boot.common.bean.init.BeanInitExample;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||
public class SpringBootCommonApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootCommonApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanInitExample beanInitExample() {
|
||||
return new BeanInitExample();
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.wyl.spring.boot.common.aop.advisor;
|
||||
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
|
||||
|
||||
/**
|
||||
* DATE 4:45 PM
|
||||
*
|
||||
* @author mzt.
|
||||
*/
|
||||
public class LogAdvisor extends AbstractBeanFactoryPointcutAdvisor {
|
||||
LogPointcut logPointcut = new LogPointcut();
|
||||
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return logPointcut;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.wyl.spring.boot.common.aop.advisor;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class LogAutoConfigure {
|
||||
@Bean
|
||||
LogPointcut logPointcut() {
|
||||
return new LogPointcut();
|
||||
}
|
||||
|
||||
@Bean
|
||||
LogAdvisor logAdvisor() {
|
||||
LogAdvisor logAdvisor = new LogAdvisor();
|
||||
logAdvisor.setAdvice(logInterceptor());
|
||||
return logAdvisor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
LogInterceptor logInterceptor() {
|
||||
return new LogInterceptor();
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.wyl.spring.boot.common.aop.advisor;
|
||||
|
||||
import com.wyl.spring.boot.common.spel.service.Evaluator;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
/**
|
||||
* @author: wangyl
|
||||
* @date: 2022/5/1
|
||||
* @description: 再方法执行前以及执行进行代理操作
|
||||
*/
|
||||
public class LogInterceptor implements MethodInterceptor {
|
||||
|
||||
|
||||
private final Evaluator evaluator = new Evaluator();
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
System.out.println("Advisor 方法执行前");
|
||||
Object proceed = invocation.proceed();
|
||||
System.out.println("Advisor 方法执行后");
|
||||
return proceed;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.wyl.spring.boot.common.aop.advisor;
|
||||
|
||||
import com.wyl.spring.boot.common.aop.annotation.LogTest;
|
||||
import org.springframework.aop.support.StaticMethodMatcherPointcut;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author: wangyl
|
||||
* @date: 2022/4/30
|
||||
* @description: apo静态切入点,切入所有matches返回true的方法
|
||||
*/
|
||||
public class LogPointcut extends StaticMethodMatcherPointcut implements Serializable {
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
LogTest annotation = method.getAnnotation(LogTest.class);
|
||||
return !Objects.isNull(annotation);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.wyl.spring.boot.common.aop.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited//注解会被继承
|
||||
@Documented
|
||||
public @interface LogTest {
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.wyl.spring.boot.common.aop.aspect;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 接口出入参数信息依赖swagger
|
||||
*
|
||||
* @author wangyl
|
||||
* @version V1.0
|
||||
* @ClassName: WebLogAspect
|
||||
* @Date: 2022/1/5 22:58
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LogAspect {
|
||||
|
||||
/**
|
||||
* 以自定义 @WebLog 注解为切点
|
||||
*/
|
||||
@Pointcut("@annotation(com.wyl.spring.boot.common.aop.annotation.LogTest)")
|
||||
public void webLog() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在切点之前织入
|
||||
*
|
||||
* @param joinPoint
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Before("webLog()")
|
||||
public void doBefore(JoinPoint joinPoint) {
|
||||
System.out.println("Aspect Before 打印");
|
||||
}
|
||||
|
||||
/**
|
||||
* 在切点之后织入
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
@After("webLog()")
|
||||
public void doAfter() {
|
||||
System.out.println("Aspect After 打印");
|
||||
}
|
||||
|
||||
/**
|
||||
* 环绕
|
||||
*
|
||||
* @param proceedingJoinPoint
|
||||
* @return
|
||||
* @throws Throwable
|
||||
*/
|
||||
@Around("webLog()")
|
||||
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
System.out.println("Aspect 方法执行前打印 打印");
|
||||
Object proceed = proceedingJoinPoint.proceed();
|
||||
System.out.println("Aspect 方法执行后打印 打印");
|
||||
return proceed;
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.wyl.spring.boot.common.bean.init;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
public class BeanInitExample implements InitializingBean, DisposableBean {
|
||||
public BeanInitExample() {
|
||||
System.out.println("构造函数被调用");
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
System.out.println("PostConstruct 被调用");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void disposable() {
|
||||
System.out.println("PreDestroy 被调用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.out.println("InitializingBean 被调用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
System.out.println("DisposableBean 被调用");
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.wyl.spring.boot.common.service;
|
||||
|
||||
import com.wyl.spring.boot.common.spel.bean.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LogTestService {
|
||||
void test();
|
||||
|
||||
void testSPEL(Order order);
|
||||
|
||||
void testSPELList(List<Order> orders);
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.wyl.spring.boot.common.service.impl;
|
||||
|
||||
import com.wyl.spring.boot.common.aop.annotation.LogTest;
|
||||
import com.wyl.spring.boot.common.service.LogTestService;
|
||||
import com.wyl.spring.boot.common.spel.annotation.SpelTest;
|
||||
import com.wyl.spring.boot.common.spel.bean.Order;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class LogTestServiceImpl implements LogTestService {
|
||||
@Override
|
||||
@LogTest
|
||||
public void test() {
|
||||
System.out.println("testLog");
|
||||
}
|
||||
|
||||
|
||||
@SpelTest(spel = "{#order.id}")
|
||||
public void testSPEL(Order order) {
|
||||
System.out.println(123);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SpelTest(spel = "{#orders.![#this.id]}")
|
||||
public void testSPELList(List<Order> orders) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.wyl.spring.boot.common.spel;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.wyl.spring.boot.common.spel.annotation.SpelTest;
|
||||
import com.wyl.spring.boot.common.spel.service.EvaluationContext;
|
||||
import com.wyl.spring.boot.common.spel.service.Evaluator;
|
||||
import com.wyl.spring.boot.common.spel.service.RootObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SpelTestAspect {
|
||||
/**
|
||||
* 日志SpEL解析器
|
||||
*/
|
||||
private final Evaluator evaluator = new Evaluator();
|
||||
|
||||
/**
|
||||
* 日志切入点
|
||||
*/
|
||||
@Pointcut(value = "@annotation(com.wyl.spring.boot.common.spel.annotation.SpelTest)")
|
||||
public void SpelTestPointCut() {
|
||||
}
|
||||
|
||||
|
||||
@Around(value = "SpelTestPointCut()")
|
||||
public Object errorLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
proceedingJoinPoint.getArgs();
|
||||
Signature signature = proceedingJoinPoint.getSignature();
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
Object[] args = proceedingJoinPoint.getArgs();
|
||||
Class targetClass = AopProxyUtils.ultimateTargetClass(proceedingJoinPoint.getTarget());
|
||||
SpelTest annotation = method.getAnnotation(SpelTest.class);
|
||||
/**
|
||||
* 生成元数据
|
||||
*/
|
||||
RootObject rootObject = new RootObject();
|
||||
/**
|
||||
* 生成spel上下文
|
||||
*/
|
||||
EvaluationContext context = new EvaluationContext(rootObject, method, args, evaluator.getDiscoverer());
|
||||
/**
|
||||
* 解析spel
|
||||
*/
|
||||
Object content = evaluator.parse(annotation.spel(), context);
|
||||
System.out.println(content);
|
||||
return proceedingJoinPoint.proceed();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.wyl.spring.boot.common.spel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SpelTest {
|
||||
/**
|
||||
* spel
|
||||
*/
|
||||
String spel();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.wyl.spring.boot.common.spel.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Order {
|
||||
Integer id;
|
||||
String name;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.wyl.spring.boot.common.spel.service;
|
||||
|
||||
import org.springframework.context.expression.MethodBasedEvaluationContext;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
/**
|
||||
* @author: wangyl
|
||||
* @date: 2022/5/8
|
||||
* @description: 解析上下文, 用于整个解析环境
|
||||
*/
|
||||
public class EvaluationContext extends MethodBasedEvaluationContext {
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param rootObject 数据来源对象
|
||||
* @param discoverer 参数解析器
|
||||
*/
|
||||
public EvaluationContext(RootObject rootObject, Method method, Object[] arguments, ParameterNameDiscoverer discoverer) {
|
||||
super(rootObject, method, arguments, discoverer);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.wyl.spring.boot.common.spel.service;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.common.TemplateParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* @author: wangyl
|
||||
* @date: 2022/5/8
|
||||
* @description: spel解析处理器
|
||||
*/
|
||||
@Getter
|
||||
public class Evaluator {
|
||||
/**
|
||||
* SpEL解析器
|
||||
*/
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser();
|
||||
/**
|
||||
* 参数解析器
|
||||
*/
|
||||
private final ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
|
||||
/**
|
||||
* 表达式模板
|
||||
*/
|
||||
private final ParserContext template = new TemplateParserContext("{", "}");
|
||||
|
||||
/**
|
||||
* 解析
|
||||
*
|
||||
* @param expression 表达式
|
||||
* @param context 日志表达式上下文
|
||||
* @return 表达式结果
|
||||
*/
|
||||
public Object parse(String expression, EvaluationContext context) {
|
||||
return getExpression(expression).getValue(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取翻译后表达式
|
||||
*
|
||||
* @param expression 字符串表达式
|
||||
* @return 翻译后表达式
|
||||
*/
|
||||
private Expression getExpression(String expression) {
|
||||
return getParser().parseExpression(expression, template);
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.wyl.spring.boot.common.spel.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author: wangyl
|
||||
* @date: 2022/5/8
|
||||
* @description: spel解析得元数据
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class RootObject {
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.wyl.spring.boot.common;
|
||||
|
||||
import com.wyl.spring.boot.common.service.LogTestService;
|
||||
import com.wyl.spring.boot.common.spel.bean.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
class SpringBootCommonApplicationTests {
|
||||
|
||||
@Autowired
|
||||
LogTestService logTestService;
|
||||
|
||||
@Test
|
||||
void beanInit() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void LogTestServiceTest() {
|
||||
logTestService.test();
|
||||
}
|
||||
|
||||
@Test
|
||||
void SpelTest() {
|
||||
Order order = new Order();
|
||||
order.setId(123);
|
||||
order.setName("wyl");
|
||||
logTestService.testSPEL(order);
|
||||
}
|
||||
|
||||
@Test
|
||||
void SpelListTest() {
|
||||
Order order1 = new Order();
|
||||
order1.setId(1);
|
||||
order1.setName("wyl1");
|
||||
Order order2 = new Order();
|
||||
order2.setId(2);
|
||||
order2.setName("wyl2");
|
||||
Order order3 = new Order();
|
||||
order3.setId(3);
|
||||
order3.setName("wyl3");
|
||||
List<Order> orders = Arrays.asList(order1, order2, order3);
|
||||
logTestService.testSPELList(orders);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.wyl.example;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
{
|
||||
/**
|
||||
* Rigorous Test :-)
|
||||
*/
|
||||
@Test
|
||||
public void shouldAnswerWithTrue()
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.wyl.example.service;
|
||||
|
||||
public interface Service {
|
||||
void test();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.wyl.example.service;
|
||||
|
||||
public class ServiceTest implements Service{
|
||||
@Override
|
||||
public void test() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user