我有一个带有许多方法的服务接口,所有这些方法都接受一个Request对象并返回一个Response对象.所有请求对象都有一个共同的祖先,所有响应对象都有一个不同的共同祖先(它有一个成功标志和一个消息字段).
现在,我希望有一个检查权限等的方面,执行服务调用并返回带有失败代码的Response对象(如果有任何失败).问题是:我需要知道要创建什么类型的Response对象.是否有切入点表达式,使我可以访问返回类型?也许是这样的事情?
@Around(value = "execution(public *"
+ " com.mycompany.MyService+.*(..))"
+ " && args(request)"
+ " && returning( returnType)" // something like this would be nice
, argNames = "request,returnType")
public Object handleServiceCall(final ProceedingJoinPoint pjp,
final Request request,
final Class<? extends Response> returnType){ ... }
Run Code Online (Sandbox Code Playgroud) 我正在学习春天,我有跟随
考虑以下bean定义:
<bean id="clientService" class="com.myapp.service.ClientServiceImpl" />
Run Code Online (Sandbox Code Playgroud)
现在考虑一下它被声明为切入点*的情况,目标是**clientService bean中的所有方法.
还要考虑ClientServiceImpl类实现3个接口
现在我知道,使用AOP的clientService bean是代理和该代理实现了所有的3个接口.
但是实现所有这三个接口的确切原因是什么?
所以在我看来,存在两种代理(如果我说错误的断言,请纠正我):
JDK代理:默认使用Spring(是真的吗?),我有一个接口,用于定义我想要代理的对象的方法.所以这个接口的具体实现是由代理包装的.所以当我在我的对象上调用一个方法时,我在它的代理上调用它.调用由最终执行方面的方法拦截器识别,然后执行调用的方法.
CGLIB代理:在我看来,代理扩展了包装对象的实现,为它添加了额外的逻辑功能
像这样的东西:

所以在我看来,Spring使用第一种基于接口实现的代理(是不是?):

我认为在AOP中,额外的逻辑由方法拦截器的实现来表示(是真的吗?),标准逻辑由定义在接口中的方法的实现来表示.
但是,如果之前的推理是正确的,我的疑问是:为什么我需要定义这些接口,并且由对象包装的对象实现这些接口?(我无法理解代理本身是否实现了这些接口).
为什么?究竟如何运作?
TNX
我想从业务类中的方法访问局部变量,方法是在方面类中.例如
class BusinessClass {
public void simpleTest() {
...
String localString = new String( "test" );
...
}
}
MyAspect {
log() {
// I WANT TO ACCESS THE VALUE OF LOCALSTRING HERE
}
}
Run Code Online (Sandbox Code Playgroud)
我想在MyAspect的log方法中访问localString的值.如果有任何方法可以使用Spring/AspectJ完成此操作,请告诉我.另外,有没有办法在不改变simpleTest方法签名的情况下完成?
非常感谢!
我已经声明了以下方面建议dao调用,我正在尝试运行@Before建议,但它不起作用.
这就是方面.
package com.hedgebenefits.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AccessControlAspect {
@Before("within(com.hedgebenefits.daos..*) && execution(public * *(..))")
public void daoCall() {
System.out.println("Before advice invoked for DAO method called ");
}
}
Run Code Online (Sandbox Code Playgroud)
我的application-context.xml具有以下标记
<aop:aspectj-autoproxy/>
Run Code Online (Sandbox Code Playgroud)
我的Dao课程如下:
package com.hedgebenefits.daos.impl;
import com.hedgebenefits.daos.AdminDao;
import com.hedgebenefits.domain.Admin;
import org.springframework.stereotype.Repository;
@Repository
public class AdminDaoImpl implements AdminDao{
@Override
public void save(Admin admin) {
}
}
Run Code Online (Sandbox Code Playgroud)
我放了一个断点,但我可以看到它不活跃,我肯定在这里做了一些愚蠢的错误,但无法搞清楚.PL.咨询.
我在启动服务器时遇到以下错误.应用程序中包含Spring和AspectJ类.
Caused by: java.lang.VerifyError: JVMVRFY013 class loading constraint violated; class=org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint, method=getSourceLocation()Lorg/aspectj/lang/reflect/SourceLocation;, pc=0
at java.lang.J9VMInternals.verifyImpl(Native Method)
at java.lang.J9VMInternals.verify(J9VMInternals.java:93)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:170)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.currentJoinPoint(AbstractAspectJAdvice.java:83)
Run Code Online (Sandbox Code Playgroud)
作为第一遍,我为企业应用程序提供了PARENT_FIRST选项

我很熟悉Spring AOP.正如我在春季文档http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/aop.html中所读到的那样,Spring AOP研究代理的概念.
在8.2.3.1支持的切入点指示符部分中,我找到了以下注释
由于Spring的AOP框架基于代理的特性,受保护的方法根据定义不会被拦截,既不用于JDK代理(这不适用),也不用于CGLIB代理(这在技术上可行,但不建议用于AOP).因此,任何给定的切入点都只能与公共方法匹配!
起初,我不相信它,所以我试图在不使用接口的情况下实现它,默认情况下所有方法都是公开的,并且对上述情况感到惊讶.由于代理类是建议/目标对象的子类,受保护的方法可以由子类访问,所以我认为受保护的方法可以正常工作.
有人可以告诉我为什么不拦截受保护的方法?我错过了什么吗?
我想完成从控制器收到的JSON响应,例如状态属性.在这方面,我将使用Aspect类,其中@Around方法返回一个自定义类对象.在这种情况下,我收到一个错误:
java.lang.ClassCastException: *.controller.RestResponse cannot be cast to java.util.List
Run Code Online (Sandbox Code Playgroud)
有没有办法通过aspectJ annotation @Around将@ResponseBody类型的返回更改为自定义类型?我无法更改控制器代码!
控制器类:
@Controller
@RequestMapping(value = "/users")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public List<User> get() throws InterruptedException {
return userService.getUsers();
}
...
}
Run Code Online (Sandbox Code Playgroud)
Aspect类:
@Component
@Aspect
public class RestInterceptor {
@Pointcut("within(* controller.api.*)")
public void endpointMethod() {
}
@Around("endpointMethod()")
public RestResponse unifyResponse(ProceedingJoinPoint pjp) throws Throwable {
Object controllerResult = pjp.proceed();
RestResponse result = new RestResponse(0, controllerResult);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
自定义类RestResponse:
public class RestResponse{
private …Run Code Online (Sandbox Code Playgroud) 我有一组非托管类,我在Spring之外实例化.我一直在尝试使用Spring AOP将加载时间编织@Autowire到这些类的bean中,但到目前为止还没有任何运气.
我一直在使用Tomcat 8和Spring Boot 1.2.0进行测试.
我@Configuration尝试设置类的位置如下所示:
@Configuration
@PropertySource("classpath:application.properties")
@EnableSpringConfigured
@EnableLoadTimeWeaving
public class Config
Run Code Online (Sandbox Code Playgroud)
在里面Config我将我想要的bean定义@Auotwire到我的非托管类中:
@Bean
public StateProvider stateProvider() {
//setup bean
return new DynamoStateProviderImpl( );
}
Run Code Online (Sandbox Code Playgroud)
非托管bean看起来像这样:
@Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true, preConstruction = true)
public class StateOutput implements UnifiedOutput {
@Autowired
private StateProvider stateProvider;
Run Code Online (Sandbox Code Playgroud)
我的pom内有以下deps
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-agent</artifactId>
<version>2.5.6.SEC03</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
到目前为止,我还没有看到任何注入stateProvider …
我正在研究Spring AOP模块,我对AROUND建议的确切运作方式有些怀疑.
阅读官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
我可以阅读有关AROUND ADVICE的内容:
围绕建议:围绕连接点的建议,例如方法调用.这是最有力的建议.around通知可以在方法调用之前和之后执行自定义行为.它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行.
这是周围建议的序列图:

因此,根据我的理解,我可以定义一个建议(我的自定义行为),它将在切入点指定的关节点之前和之后执行.
例如,我可以用这种方式定义AROUND ADVICE:
@Around(“execution(@example.Cacheable * rewards.service..*.*(..))”)
public Object cache(ProceedingJoinPoint point) throws Throwable {
Object value = cacheStore.get(cacheKey(point));
if (value == null) {
value = point.proceed();
cacheStore.put(cacheKey(point), value);
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
在调用服务方法之前和之后执行实现的chaching行为.这样对吗?
我无法完全理解的是它是如何使用ProceedingJoinPoint点参数的.
根据我的理解,它用于选择执行或不执行特定操作但具体如何工作?
另一个疑问是如何正确使用AOP建议如何回答以下问题:
如果我想尝试捕获异常,我必须使用哪些建议?
我认为在这种情况下,答案是使用After throw通知,因为当匹配的方法执行通过抛出异常退出时,通知会执行.
但我不确定它,因为根据我的理解,只有在方法抛出异常时才会执行建议.或者在这种情况下我必须使用**AROUND ADVICE*?
TNX
我在我的Web应用程序中使用Spring 4.2.4.RELEASE,我想从中删除对aspectjweaver.jar的依赖.我不直接使用AOP,我当然不使用AspectJ.但我的应用程序失败,出现以下异常:
java.lang.ClassNotFoundException: org.aspectj.util.PartialOrder$PartialComparable
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:450)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:403)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at org.eclipse.jetty.webapp.WebAppClassLoader.findClass(WebAppClassLoader.java:510)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:441)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:403)
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.sortAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:73)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:91)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:346)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
Run Code Online (Sandbox Code Playgroud)
有什么方法可以完全删除对aspectjweaver.jar的依赖吗?
spring-aop ×10
spring ×8
java ×7
aspectj ×4
aop ×3
pointcuts ×1
protected ×1
proxy ×1
return ×1
spring-boot ×1
spring-mvc ×1
websphere ×1