Java 如何在建议之前增加Spring方法中使用的参数
我从我的Java语言老师那里得到一项任务,在建议之前使用SpringAOP增加RESTfulWeb服务中的计数器(id)。我不知道怎么做。我们使用spring.io中的默认restful应用程序。这是我修改过的代码: 应用程序:Java 如何在建议之前增加Spring方法中使用的参数,java,spring,spring-boot,aop,aspectj,Java,Spring,Spring Boot,Aop,Aspectj,我从我的Java语言老师那里得到一项任务,在建议之前使用SpringAOP增加RESTfulWeb服务中的计数器(id)。我不知道怎么做。我们使用spring.io中的默认restful应用程序。这是我修改过的代码: 应用程序: package sut.ist012m.Ruygo.hello_goodbye; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfig
package sut.ist012m.Ruygo.hello_goodbye;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class Application {
public static void main(String[] args) {
final ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
final Controller Controller = run.getBean(Controller.class);
}
}
控制器:
package sut.ist012m.Ruygo.hello_goodbye;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
private static final String hellotemplate = "Hello, %s!";
private static final String adrtemplate = "Welcome to %s";
public AtomicLong counter1 = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name,
@RequestParam(value="city", defaultValue="Moscow") String city) {
return new Greeting(counter1.incrementAndGet(),
String.format(hellotemplate, name),
String.format(adrtemplate, city));
}
}
问候:
package sut.ist012m.Ruygo.hello_goodbye;
public class Greeting {
private final long id;
private final String content;
private final String adrcontent;
public Greeting( long id,
String content,
String adrcontent) {
this.id = id;
this.content = content;
this.adrcontent = adrcontent;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
public String getAdrcontent() {
return adrcontent;
}
反方面(我写的):
在正常情况下,然后你们刷新网页你们会看到id=1,id=2,id=3。。。
我们希望看到id=1,11,21,23等等。
我不明白在“建议前公开无效”中该写些什么。
Spring不控制“Greeting”类可以吗?不能使用before-advice修改参数/参数,必须使用around-advice修改参数
@Around(value="execution(* sut.ist012m.Ruygo.hello_goodbye.Greeting.*(..)) ")
public void aroundAdvice(ProceedingJoinPoint pjp){
Object[] args = pjp.getArgs();
// you can modify it by modifying args
args[0] = .....; // modify your first parameter (id)
args[1] = .....; // modify your second parameter (content)
args[2] = .....; // modify your third parameter (adrcontent)
// call proceed method from pjp and pass args as its parameter
pjp.proceed(args);
}
SpringAOP将只建议SpringBeans。因此,您所关心的“Spring不控制“Meeting”类可以吗?”(我猜您在这里指的是问候语)是正确的。这是不好的,因为你试图建议一个问候豆 还要注意的是,使用SpringAOP不能向构造函数提供建议 如果您的拦截需要包括方法调用甚至构造函数 在目标类中,考虑使用弹簧驱动的本机。 AspectJ编织代替了Spring基于代理的AOP框架 为了更好地理解以下代码,您必须通读以下参考资料 使用SpringAOP实现您的需求有多种方法,我只是遵循您的建议 修改了GreetingController并自动连接了一个具有作用域请求的问候bean
@RestController
public class GreetingController {
private static final String hellotemplate = "Hello, %s!";
private static final String adrtemplate = "Welcome to %s";
@Autowired
Greeting greeting;
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name,
@RequestParam(value = "city", defaultValue = "Moscow") String city) throws Exception {
greeting.setAdrcontent(String.format(adrtemplate, city));
greeting.setContent(String.format(hellotemplate, name));
Greeting g = getTarget(greeting);
return g;
}
// Get the actual target object to avoid exception when returning
// Comment out this method to observe what happens.
private Greeting getTarget(Greeting greeting) throws Exception {
while (AopUtils.isAopProxy(greeting) && greeting instanceof Advised) {
Object target = ((Advised) greeting).getTargetSource().getTarget();
greeting = (Greeting) target;
}
return greeting;
}
}
将问候语类修改为Springbean
@Component
@RequestScope
public class Greeting {
private long id;
private String content;
private String adrcontent;
// Getters and setters
}
反方面
@Aspect
@Component
public class CounterAspect {
public AtomicLong counter1 = new AtomicLong(1);
@Before(value = "execution(* sut.ist012m.Ruygo.hello_goodbye.Greeting.*(..)) && target(greeting)")
public void beforeAdvice(Greeting greeting) {
if (greeting.getId() == 0) {
greeting.setId(counter1.getAndAdd(10));
System.out.println(greeting.getId());
}
}
}
此通知针对问候语bean上的任何公共方法调用执行,并通过问候语
参数使实际的问候语对象可用于通知。(请参阅:)
作为工作的一部分,您可以尝试不同的方法来优化此代码。非常感谢!这真是个好建议!很高兴这有帮助。如果您的问题得到了回答,请将此标记为答案(勾选标记),如果它对您有帮助,也请向上投票。(向上箭头)
@Aspect
@Component
public class CounterAspect {
public AtomicLong counter1 = new AtomicLong(1);
@Before(value = "execution(* sut.ist012m.Ruygo.hello_goodbye.Greeting.*(..)) && target(greeting)")
public void beforeAdvice(Greeting greeting) {
if (greeting.getId() == 0) {
greeting.setId(counter1.getAndAdd(10));
System.out.println(greeting.getId());
}
}
}