我需要通过使用注释作为切入点来接受一些方法及其属性,但是如何访问这些方法属性.我有以下代码,可以在方法运行之前成功运行代码,但我只是不知道如何访问这些attrbiutes.
package my.package;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MyAspect {
@Pointcut(value="execution(public * *(..))")
public void anyPublicMethod() {
}
@Around("anyPublicMethod() && @annotation(myAnnotation )")
public Object myAspect(ProceedingJoinPoint pjp, MyAnnotation myAnnotation)
throws Throwable {
// how can I access method attributes here ?
System.out.println("hello aspect!");
return pjp.proceed();
}
}
Run Code Online (Sandbox Code Playgroud) 我正在关注Javabrains的spring方面编程教程.我特意在本教程中:http://javabrains.koushik.org/2011/08/spring-tutorial-27-writing-our-first.html我将所需的库导入到项目中,我没有得到任何警告IDE,但是当我运行代码时,我得到以下异常:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at org.koushik.javabrains.AopMain.main(AopMain.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getPointcut(ReflectiveAspectJAdvisorFactory.java:145)
at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:130)
at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory$1.doWith(ReflectiveAspectJAdvisorFactory.java:74)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:473)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:451) …Run Code Online (Sandbox Code Playgroud) 我想为使用特定注释注释的私有方法创建一个Pointcut.但是,当注释位于如下所示的私有方法时,不会触发我的方面.
@Aspect
public class ServiceValidatorAspect {
@Pointcut("within(@com.example.ValidatorMethod *)")
public void methodsAnnotatedWithValidated() {
}
@AfterReturning(
pointcut = "methodsAnnotatedWithValidated()",
returning = "result")
public void throwExceptionIfErrorExists(JoinPoint joinPoint, Object result) {
...
}
Run Code Online (Sandbox Code Playgroud)
服务接口
public interface UserService {
UserDto createUser(UserDto userDto);
}
Run Code Online (Sandbox Code Playgroud)
服务实施
public class UserServiceImpl implements UserService {
public UserDto createUser(UserDto userDto) {
validateUser(userDto);
userDao.create(userDto);
}
@ValidatorMethod
private validateUser(UserDto userDto) {
// code here
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将注释移动到公共接口方法实现createUser,则会触发我的方面.我应该如何定义切入点或配置我的方面以使我的原始用例工作?
在我的请求中,我有一个参数名称"accessToken",如何从ProceedingJoinPoint获取请求参数值?
public Object handleAccessToken(ProceedingJoinPoint joinPoint) throws Throwable {
final Signature signature = joinPoint.getStaticPart().getSignature();
if (signature instanceof MethodSignature) {
final MethodSignature ms = (MethodSignature) signature;
String[] params = ms.getParameterNames();
for (String param : params) {
System.out.println(param);
// here how do i get parameter value using param ?
}
}
}
Run Code Online (Sandbox Code Playgroud)
通话方式:
public MyResponse saveUser(
@RequestParam("accessToken") String accessToken,
@RequestBody final UserDto userDto
) {
// code
}
Run Code Online (Sandbox Code Playgroud)
我想在AOP中获取此访问令牌.
提前致谢.
我正在寻找一个功能或软件,他将允许我轻松地分析我的方法执行时间,并选择通过包过滤器分析的内容.
我知道,它是分析器101.我使用TPTP分析器.但我对它并不满意.坦率地说,我只是不明白它是如何工作的,当我描述我的应用程序(在分析模式下启动服务器)时,它将永远无所事事.(好吧,不是我的期望:简单的执行时间输出)
所以我用系统时间自己进行分析(在方法的开头和结尾添加一行).也不是那么坏.
我的问题是:我想在使用Spring AOP调用方法之前和之后测量系统时间,你能给我指点吗?这是一个好/坏的主意?代码库非常大,我们没有很多单元测试,难道不是"危险"吗?
我不是要求代码,我想我可以用这种链接自己做:http: //static.springsource.org/spring/docs/2.5.x/reference/aop.html
但如果你有一个很好的教程(以前从未做过AOP,只知道这个概念),我就接受了.
我们有一个在App Engine上运行并使用Spring框架的应用程序.最近我们添加了一些基于AOP的新功能.我们决定使用@AspectJ样式,因此我们添加<aop:aspectj-autoproxy>到基于XML的配置中并实现了各自的方面.一切都在开发服务器上运行正常,但是,当部署到云环境时,我们java.lang.StackOverflowError每次初始化应用程序时都会得到.
无法创建并导致错误的bean是使用@Configuration注释注释的配置类.看来基本上任何配置bean都可能导致错误.
您可以在下面看到相应的堆栈跟踪.
org.springframework.web.context.ContextLoader initWebApplicationContext: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectifyConfig' defined in URL [jar:file:/base/data/home/apps/{app-id}/8.372375422460842231/WEB-INF/lib/{app-name}-1.0-SNAPSHOT.jar!/{path-to-class}/ObjectifyConfig.class]: Initialization of bean failed; nested exception is java.lang.StackOverflowError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:219)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:194)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:134)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435) …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring框架(4.0.5)和AspectJ进行AOP Logging开发一个java(JDK1.6)应用程序.
我的Aspect类工作正常,但我无法为构造函数对象创建切入点.
这是我的目标:
@Controller
public class ApplicationController {
public ApplicationController(String myString, MyObject myObject) {
...
}
...
..
.
}
Run Code Online (Sandbox Code Playgroud)
这是我的Aspect类:
@Aspect
@Component
public class CommonLogAspect implements ILogAspect {
Logger log = Logger.getLogger(CommonLogAspect.class);
// @Before("execution(my.package.Class.new(..)))
@Before("execution(* *.new(..))")
public void constructorAnnotatedWithInject() {
log.info("CONSTRUCTOR");
}
}
Run Code Online (Sandbox Code Playgroud)
如何为构造函数对象创建切入点?
谢谢
我正在研究Spring AOP,我有以下疑问.
据我所知,有两种方法可以将AOP行为实现到Java应用程序中:
AspectJ:这是第一个使用字节码修改进行方面编织的原始AOP技术.
Spring AOP:基于Java的AOP框架,使用AspectJ集成,使用动态代理进行方面编织.
我的疑问是:究竟什么意味着Spring AOP是一个带有AspectJ集成的AOP框架?那么它依次使用AspectJ?或者是什么?
第二个疑问与Spring AOP的Spring配置有关,我知道我可以这样做:
1)使用Java配置类:
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages=“com.example”)
public class AspectConfig {
...
}
Run Code Online (Sandbox Code Playgroud)
2)使用XML:
<beans>
<aop:aspectj-autoproxy />
<context:component-scan base-package=“com.example” />
</beans>
Run Code Online (Sandbox Code Playgroud)
因此,在两种配置中,Spring AOP似乎都使用AspectJ,因为在这些配置中我有:@EnableAspectJAutoProxy和
它究竟意味着什么?
我正在使用Spring 4.16并且我有我的ValidationAspect,它验证方法参数并抛出ValidationException如果有问题.这是在我运行服务器并发送请求时调用,但不是在测试时调用:
package com.example.movies.domain.aspect;
...
@Aspect
public class ValidationAspect {
private final Validator validator;
public ValidationAspect(final Validator validator) {
this.validator = validator;
}
@Pointcut("execution(* com.example.movies.domain.feature..*.*(..))")
private void selectAllFeatureMethods() {
}
@Pointcut("bean(*Service)")
private void selectAllServiceBeanMethods() {
}
@Before("selectAllFeatureMethods() && selectAllServiceBeanMethods()")
public synchronized void validate(JoinPoint joinPoint) {
// Validates method arguments which are annotated with @Valid
}
}
Run Code Online (Sandbox Code Playgroud)
配置文件,我创建方面bean的方面
package com.example.movies.domain.config;
...
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AspectsConfiguration {
@Bean
@Description("Hibernate validator. Used to validate request's input")
public Validator validator() { …Run Code Online (Sandbox Code Playgroud) 我有一个用@Transactional 和另一个自定义注释@Custom 注释的方法。此自定义注释包含在建议中。操作顺序如下:
1.Transactional method gets called
2.Sees @Transactional and @Custom
3.As @Custom is intercepted by around advice, it first executes code before invocation of method
4.invocationContext.proceed()
5.Transaction gets created
6.Actual method runs
7.Back to around advice and executes code after method invocation
Run Code Online (Sandbox Code Playgroud)
我想在调用建议之前创建事务。像下面这样:
1.Transactional method gets called
2.Sees @Transactional and @Custom
3.Transaction gets created (propagate this transaction to @Custom)
4.As @Custom is intercepted by around advice, it first executes code before invocation of method
5.invocationContext.proceed()
6.Actual method runs
7.Back …Run Code Online (Sandbox Code Playgroud)