我在"aspectj"模式下使用Spring的声明式事务(@Transactional注释).它在大多数情况下都可以完全像它应该的那样工作,但对于其中一个它没有.我们可以称之为Lang(因为这就是它实际上所称的).
我已经能够确定加载时间织布机的问题.通过打开aop.xml中的debug和verbose日志记录,它列出了所有正在编织的类.Lang根本没有在日志中提到有问题的类.
然后我在顶部放置了一个断点Lang,导致Eclipse在Lang加载类时挂起线程.当LTW编织其他类时,这个断点被击中!所以我猜测它要么编织也要Lang失败并且不输出,或者其他一些类有一个引用强制它Lang在实际有机会编织它之前加载.
我不确定如何继续调试这个,因为我无法以较小的规模重现它.有关如何继续的任何建议?
更新:其他线索也欢迎.例如,LTW实际上如何运作?似乎有很多魔法发生.是否有任何选项可以从LTW获得更多的调试输出?我目前有:
<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
Run Code Online (Sandbox Code Playgroud)
我忘了汤姆之前提到它:弹簧剂被用来允许LTW,即InstrumentationLoadTimeWeaver.
根据Andy Clement的建议,我决定检查AspectJ变压器是否甚至通过了这门课程.我放了一个断点ClassPreProcessorAgent.transform(..),看起来这个Lang类甚至都没有到达那个方法,尽管它被与其他类(Jetty的WebAppClassLoader的一个实例)相同的类加载器加载.
然后我接着断了一个断点InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..).甚至没有一个被击中Lang.我相信应该为所有加载的类调用该方法,无论他们使用什么类加载器.这开始看起来像:
Lang在Eclipse报告时没有加载接下来的线索:我打开了-verbose:class,看起来好像Lang 是过早加载 - 可能是在变压器添加到Instrumentation之前.奇怪的是,我的Eclipse断点没有捕获到这个加载.
这意味着Spring是新的嫌疑人.在ConfigurationClassPostProcessor负载类中似乎有一些处理来检查它们.这可能与我的问题有关.
这些行ConfigurationClassBeanDefinitionReader导致Lang类被读取:
else if (metadata.isAnnotated(Component.class.getName()) ||
metadata.hasAnnotatedMethods(Bean.class.getName())) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
return true;
}
Run Code Online (Sandbox Code Playgroud)
特别是对类的metadata.hasAnnotatedMethods()调用getDeclaredMethods(),它加载该类中所有方法的所有参数类.我猜这可能不是问题的结束,因为我认为这些类应该被卸载.JVM是否可以出于不可知的原因缓存类实例?
我正在使用X.jar并添加到我的AspectJ项目(在eclipse中).我已经为X.jar中的方法myMethod()编写了切入点和建议.
但aspectj不拦截此方法调用.
我怎么能告诉aspectj拦截外部jar上的方法调用.或者它不可能吗?
谢谢
我刚刚下载了OEPE(Kepler)并安装了m2e和m2e-wtp连接器.我发现在这条路径下:首选项 - > Maven->生命周期映射 - >打开工作区生命周期映射数据有一个预先配置的xml文件,该文件说maven应该忽略AspectJ的编译目标,我认为这就是为什么AspectJ运行时库是未添加到项目中,因此eclipse不会将项目识别为AspectJ项目.
<?xml version="1.0" encoding="UTF-8"?>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<versionRange>1.6</versionRange>
<goals>
<goal>compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
Run Code Online (Sandbox Code Playgroud)
我在xml文件中注释掉了这些行并再次重新加载.现在IDE不会忽略生命周期中的AspectJ插件标记,但是pom文件抱怨它无法识别执行标记.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
使用indigo,m2e-wtp能够识别<execution>aspectj插件的标签,并能够自动将AspectJ运行时库添加到项目中,尽管在开普勒中并非如此.(我认为m2e-wtp的工作是将一个AspectJ项目从pom中取出但不太确定.)
顺便说一句.我怎么能像Indigo那样让事情发挥作用?我知道我可以右键单击项目并将其转换为Aspect项目以解决问题,但我希望IDE和插件从pom文件中实现该项目需要AspectJ jar.任何的想法?
我正在尝试设置@Configurable域对象(不是由spring容器管理).
我已经通过添加-javaagent:path/to/spring-instrument.jar作为JVM参数来完成这项工作但是我不能100%清楚这个-javaagent是否必须到位.我在Tomcat 8上运行它.我可能会误解文档,但似乎我可以使用另一种机制来实现这一点,特别是这一行:
不要定义
TomcatInstrumentableClassLoader了对Tomcat 8.0高.相反,让SpringInstrumentableClassLoader通过TomcatLoadTimeWeaver策略自动使用Tomcat的新本机设施.
代码示例如下:
@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Bean
public MyService myService(){
return new MyService();
}
}
Run Code Online (Sandbox Code Playgroud)
@Configurable
public class MyDomainObject {
@Autowired
private MyService myService;
public MyService getMyService(){
return myService;
}
}
Run Code Online (Sandbox Code Playgroud)
public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
public void test(){
log.info("test");
}
}
Run Code Online (Sandbox Code Playgroud)
那么有没有办法在不指定-javaagent的情况下编织这些@Configrable对象?我有兴趣学习如何在将WAR作为WAR部署到独立Tomcat 8服务器和/或在作为'胖'jar启动时使用嵌入式Tomcat 8服务器时完成此操作. …
aspectj load-time-weaving tomcat8 spring-boot embedded-tomcat-8
我有一个Java EE Web服务(REST),现在想使用AspectJ来创建一个规则,打印出每个传入的服务调用及其参数.
我刚刚阅读了本 教程并实现了以下代码:
的pom.xml
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8 </encoding>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
<!-- use this goal to weave all your test classes -->
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)
...并创建了一个Test.aj文件,带有一个Pointcut,它应该在调用getSignOfLife()后打印出一个teststring:
import de.jack.businesspartner.service.BusinessPartnerServiceImpl;
public aspect TestAspectJ {
pointcut getSignOfLife() :
call(void BusinessPartnerServiceImpl.getSignOfLife());
before() : …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用@Timed(http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/annotation/package-summary.html)等注释自动将指标发布到我的MetricRegistry .
这不是开箱即用的.在搜索问题时,我发现了Codahale Metrics:在普通Java中使用@Timed指标注释,其中提到了这个工作的唯一方法是使用aspectj.我将此添加到我的项目中,但仍未在MetricRegistry中看到我的指标.
这是我的pom文件.我添加了一个librato库,它加载了com.codahale.metrics:metrics-annotation.
<dependency>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
<version>${metrics-aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<dependency>
<groupId>com.librato.metrics</groupId>
<artifactId>metrics-librato</artifactId>
<version>${metrics-librato.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这就是我尝试使用指标的方式
@Metrics(registry = "default") // this.metricRegistry is default
public class Foo {
@Inject
private MetricRegistry metricRegistry;
...
@Metered(name = "meterName")
public void bar() { …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Spring和AspectJ实现加载时间编织.据我所知,我已经正确配置了所有内容,但是当我尝试运行集成测试时,我不断收到错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1079)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:643)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:407)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.boku.risk.service.perisistence.PersistenceTestBase.setupBase(PersistenceTestBase.java:23)
at com.boku.risk.service.dao.CountryLimitDaoTest.setup(CountryLimitDaoTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native …Run Code Online (Sandbox Code Playgroud) 有没有人有使用OSGi 4.3+ Weaving Hook服务的例子?使用AspectJ,ASM,JavaAssist怎么样?有人在使用OSGi WeavingHooks吗?
OSGi Core 5.0.0第56.2节中的示例简单地省略了实际的编织,并说"最后的编织留给了读者".
我的目标是:
我的问题主要是#3.
我目前正在尝试使用AspectJ WeavingAdaptor进行编织,但是我在使用方面库时遇到了问题,因为它期望构造函数中的java.net.URL [] aspectURLs是jar或目录它可以在文件系统上找到,而不是捆绑.另外,我不知道如何通过回调的处理由韦弗产生的任何新类acceptClass(字符串名称,字节[])的方法GeneratedClassHandler.
也许WeavingAdaptor不适合开始编织?或者也许我不应该使用AspectJ?
MyAnnotation.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
Run Code Online (Sandbox Code Playgroud)
MyWeavingHook.java
public class MyWeavingHook implements WeavingHook {
public class MyWeavingClassloader implements WeavingClassLoader {
private Bundle b;
public MyWeavingClassLoader(Bundle b) {
this.b = b;
}
void acceptClass(java.lang.String name, byte[] bytes) {
//no way to get this back into the woven classes bundle classloader?
}
URL[] getAspectURLs() …Run Code Online (Sandbox Code Playgroud) Say Service调用需要应用日志方面(注释)的Dao类.我想知道方面实际上是如何应用的.
根据我在服务对象下注入DAO时的理解,spring发现有一些方面(在这种情况下是日志记录)是为DAO配置的,因此它会注入代理对象而不是实际的目标对象.现在,当对DAO中的任何方法进行实际调用时,代理应用方面,然后调用实际的目标对象.那是对的吗 ?另外我相信这叫做跑步编织.
另一方面,可以使用加载时间编织(使用javaagent配置)完成相同的操作,其中对需要应用方面的类执行字节代码操作.所以代理不会在这里出现.
如果我错了,请纠正我,因为这是所有弹簧模块的基础?
我正在尝试使用类似的东西org.springframework.cache.annotation.Cacheable:
自定义注释:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckEntity {
String message() default "Check entity msg";
String key() default "";
}
Run Code Online (Sandbox Code Playgroud)
方面:
@Component
@Aspect
public class CheckEntityAspect {
@Before("execution(* *.*(..)) && @annotation(checkEntity)")
public void checkEntity(JoinPoint joinPoint, CheckEntitty checkEntity) {
System.out.println("running entity check: " + joinPoint.getSignature().getName());
}
}
Run Code Online (Sandbox Code Playgroud)
服务:
@Service
@Transactional
public class EntityServiceImpl implements EntityService {
@CheckEntity(key = "#id")
public Entity getEntity(Long id) {
return new Entity(id);
}
}
Run Code Online (Sandbox Code Playgroud)
我的IDE(IntelliJ)没有看到任何与key = "#id"使用有关的特殊情况,与使用Cacheable不同颜色而不是纯文本的类似用法相比.我提到IDE部分只是作为一个提示,如果有帮助,看起来IDE预先知道这些注释或它只是意识到我的例子中不存在的一些连接.
checkEntity.key中的值为"#id"而不是预期的数字.我尝试使用ExpressionParser但可能不是以正确的方式. …
aspectj ×10
java ×5
aop ×3
spring ×3
maven ×2
spring-aop ×2
annotations ×1
dropwizard ×1
java-8 ×1
librato ×1
lifecycle ×1
osgi ×1
spring-boot ×1
spring-el ×1
tomcat8 ×1
web-services ×1