简介:我正在使用Java与Spring boot 2.2.2和Lombok
我得到了这个示例类:
package com.example.demo.classz;
import com.example.demo.pack.MyAnnotation;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
public class FooClass {
@NonNull
@MyAnnotation
private String str;
private String uninterceptedString;
}
我想拦截所有用@MyAnnotation注释的“get”/“set”方法的调用。为了管理这个,我创建了这个界面:
package com.example.demo.pack;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {}
这个类做一些操作。
package com.example.demo.pack;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class AnnotatedFieldAspect {
@Before("execution(* com.example.demo.classz.*.get*(..)) && @annotation(com.example.demo.pack.MyAnnotation)")
public void interceptRead(JoinPoint thisJoinPoint) {
log.info(thisJoinPoint.toString());
}
@Before("execution(* com.example.demo.classz.*.set*(..)) && @annotation(com.example.demo.pack.MyAnnotation) && args(newValue)")
public void interceptWrite(JoinPoint thisJoinPoint, Object newValue) {
log.info(thisJoinPoint + " -> " + newValue);
}
}
最后为了测试所有,我做了一个简单的控制器
package com.example.demo;
import com.example.demo.classz.FooClass;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/")
public String test() {
FooClass fooClass = new FooClass("Foo");
fooClass.setStr("Foo2");
fooClass.getStr();
return "Hi";
}
}
我无法激活这些切入点,我不明白为什么。你能帮我吗?
我已经在StackOverflow上看到了一些类似的问题,比如:-带注释字段的Spring AOP切入点表达式-@AspectJ切入点,用于具有特定注释的类的所有方法
还有一些,但即使有他们的解决方案,我也没有成功。
一些配置的东西:
@EnableAspectJAutoProxy
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
和构建中的依赖项部分。格拉德尔:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.session:spring-session-core'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.2.2.RELEASE'
// compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.5'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
谢谢
正如kriegaex所提到的,FooClass不是由Spring容器管理的bean。你只能拦截一个春豆。
如果切入点表达式有效,则对代码更改的更改将使setter方法被拦截。
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
@Component
@Scope(scopeName="prototype")
public class FooClass {
@NonNull
@MyAnnotation
private String str;
private String uninterceptedString;
}
并从应用程序上下文中获取FooClass bean。
FooClass fooClass = ctx.getBean(FooClass.class,"Foo");
fooClass.setStr("Foo2");
fooClass.getStr();
阅读有关@Component和@Scope的更多信息,以了解所做的更改。
@组件@范围
注意,Spring AOP只能拦截方法调用。在此处阅读文档
==SpringAOP能力和目标
Spring AOP目前仅支持方法执行连接点(建议在Spring bean上执行方法)。没有实现字段拦截,尽管可以在不破坏核心Spring AOP API的情况下添加对字段拦截的支持。如果您需要建议字段访问和更新连接点,请考虑使用一种语言,例如AeyJ。
出于同样的原因,以下Spring AOP PointCut表达式在您的情况下是有效的
@Before("execution(* com.example.demo.classz.*.get*(..))")
public void interceptRead(JoinPoint thisJoinPoint) {
log.info(thisJoinPoint.toString());
}
@Before("execution(* com.example.demo.classz.*.set*(..)) && args(newValue)")
public void interceptWrite(JoinPoint thisJoinPoint, Object newValue) {
log.info(thisJoinPoint + " -> " + newValue);
}
我有一把刀: 问题是,当我试图使用DAO进行加载调用时,使用DynamoDBMapper以field d1作为哈希键来获取项目,它会抛出一个DynamoDBExc0019,说:为公共DAO. getField2()找到了空键,但实际上表的值对应于field d2。问题,这是因为Lombok注释而不是手动突变代码,还是一般来说我们一起使用Lombok和DynamoDBAnnotions?
我有一个Java8/Maven/Spring Boot项目。我使用Javers来审核应用程序中的更改,然而,我创建了一个自定义注释,它放在类中的字段上方,如果更改,我希望对其进行审核。下面是一个示例类:
我试图使用Hibernate的JPA注释实现以下关联: 或者,我需要基于主键进行带注释的关联。 如何实现这一点? 示例取自备用键上的Hibernate关联
我试图在方法注释上创建一个Aeyj切入点,但我总是用不同的方法失败。我使用的是aspectj自动代理(我在Spring上下文中没有配置其他编织)。我的类如下所示: 所以我想知道为什么aspectj不会创建切入点。我设法使用执行(**(…)使其工作抛出一些exc)这对我来说很好,但我仍然想知道我做错了什么。 另外,由于是在接口中定义的,我指定了实现类的注释,有没有办法让它以这种方式工作?其他代理机制
问题内容: 我正在运行Jersey REST服务。代表我的资源的POJO是带有JAXB(XML)注释的简单Java类(它们是从模式定义生成的-因此具有注释)。 我希望Jersey / Jackson忽略XML注释。我确实在我的web.xml这个配置(如提到这里): 我现在希望@XMLElement批注不再用于JSON字段命名策略。 但是看这个java领域(成员) 我仍然得到以下JSON表示形式: