弹簧自动装配bean是空
我有以下Spring配置:弹簧自动装配bean是空
<context:component-scan base-package="uk.co.mysite.googlecontactsync.aop"/>
<bean name="simpleEmailSender" class="uk.co.mysite.util.email.simple.SimpleEmailSenderImplementation"/>
<aop:aspectj-autoproxy/>
然后,我有一个方面:
@Aspect
public class SyncLoggingAspect {
@Autowired
private SimpleEmailSender simpleEmailSender
@AfterReturning(value="execution(* uk.co.mysite.datasync.polling.Poller+.doPoll())", returning="pusher")
public void afterPoll(Pusher pusher) {
simpleEmailSender.send(new PusherEmail(pusher));
}
}
这方面的工作(我可以打到afterPoll断点)但simpleEmailSender为null。不幸的是,我找不到明确的文件说明这是为什么。 (根据记录,我simpleEmailSender豆存在并正确连接到其他类)下面的事情让我困惑:
- 与上下文:组件扫描应该是捡@Aspect?如果它肯定会是一个spring管理bean,那么autowired应该可以工作吗?
- 如果上下文:组件扫描不用于创建方面,我的方面是如何创建的?我认为aop:aspectj-autoproxy只是创建一个beanPostProcessor来代理我的@Aspect类?如果它不是一个弹簧管理bean,它会怎么做?
显然你可以告诉我没有理解事情应该如何从头开始工作。
aspect是一个单例对象,它是在Spring容器之外创建的。具有XML配置的解决方案是使用Spring的工厂方法来检索方面。
<bean id="syncLoggingAspect" class="uk.co.demo.SyncLoggingAspect"
factory-method="aspectOf" />
利用这种构造方面都将被视为任何其他Spring bean和自动装配将工作正常。
您还必须在Enum对象和其他没有构造函数的对象或在Spring容器外创建的对象上使用工厂方法。
从我可以在文档中看到的这是用于使用AspectJ时。我应该使用弹簧AOP。在我的配置中是否有某些东西我缺少/需要添加以使其成为例子? – mogronalol 2012-03-12 09:28:55
想出来后,你确实给我的解决方案,但现在的我,因为我的上述观点仍然感到困惑 – mogronalol 2012-03-12 11:52:19
春天文档是笨重。可配置为非单身人士。 – lwpro2 2014-05-21 01:29:17
另一种选择是将@Configurable
添加到您的方面类中,而不是混淆XML。
尼斯。还记得XML中的
谢谢! '@ Configurable'为我做了诀窍。不需要任何单独的JavaConfig或XML factory-method ='aspect-of'和'@ Configurable'注释。 – 2013-11-29 22:03:58
我刚刚遇到过这种情况,当Spring上下文刷新时,Spring不会自动更新引用。我在http://stackoverflow.com/q/22826526/827480上发布了一个问题,寻找解决这个问题的方法。 – 2014-04-03 02:08:02
这blog post解释得很好。由于这方面的单身是Spring容器之外创建你需要用factory-method =” aspectOf”它是通过AspectJ织在后才可用(不是Spring AOP):
通知工厂-method =“aspectOf”告诉Spring使用真实的AspectJ(而不是Spring AOP)方面来创建这个bean。所以 方面编织后有一个 “aspectOf”的方法。
这样:
没有匹配的工厂方法发现:工厂方法 'aspectOf()' - 这 将意味着方面没有被AspectJ织入编织。
从我使用spring 3.1的经验来看,如果我不使用@Autowired而是传统的setter进行依赖注入,它会被注入并按预期工作,没有aspectJ weaver。尽管我在单身方面遇到问题......它导致了'perthis'实例化模型。 。
仅配置java config(因此没有基于XML的配置)配置@Autowired需要一点额外的工作,而不仅仅是将@Configuration添加到类中,因为它还需要aspectOf方法。
什么工作对我来说是创建一个新类:
@Component
public class SpringApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
,然后使用你的方面结合使用@DependsOn @Configured和@Autowired:
@DependsOn("springApplicationContextHolder")
@Configuration
@Aspect
public class SomeAspect {
@Autowired
private SomeBean someBean;
public static SomeAspect aspectOf() {
return SpringApplicationContextProvider.getApplicationContext().getBean(SomeAspect.class);
}
的是@DependsOn因为Spring无法确定依赖关系,因为bean是静态使用的。
谢谢你,因为这是我能找到的唯一基于注释的例子。 – mag382 2013-11-07 18:10:31
CheckServicesPermissionsAspect.class?我不明白这是什么。 – sudeepdino008 2014-06-19 09:20:13
这是一个来自现有项目的副本,但我忘了概括这一点,现在修复:) – Wouter 2014-06-19 11:29:05
添加@Component对方面类和你的依赖应该得到自动注入。 并添加背景:组件扫描程序包在您的方面是在Spring上下文文件。
@Component
@Aspect
public class SomeAspect {
/* following dependency should get injected */
@Autowired
SomeTask someTask;
/* rest of code */
}
这实际上对我有用。 – dantebarba 2016-12-29 15:05:42
我没有50个代表发表评论,因此这里是另一个与@ Jitendra Vispute答案有关的答案。 官方春天文档中提到:
你可以在你的Spring XML配置寄存器的方面类定期豆类,或通过使用classpath扫描自动检测他们 - 就像任何其他的Spring管理的bean。但是,请注意@Aspect注解不足以在classpath中自动检测:为了这个目的,你需要添加一个单独的@Component注释(或可选择地有资格,按照Spring的组件扫描仪的规则自定义构造型注解)。 Source: Spring '4.1.7.Release' documentation。
这将意味着在配置中添加@Component注释并添加@ComponentScan将使@Jitendra Vispute的示例工作。对于春季启动aop示例它的工作,虽然我没有搞乱上下文刷新。 Spring boot aop sample:
应用:
package sample.aop;
@SpringBootApplication
public class SampleAopApplication implements CommandLineRunner {
// Simple example shows how an application can spy on itself with AOP
@Autowired
private HelloWorldService helloWorldService;
@Override
public void run(String... args) {
System.out.println(this.helloWorldService.getHelloMessage());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleAopApplication.class, args);
}
}
该应用程序还应该运行与以下注释,而不是@SpringBootApplication纯Spring框架的应用:
- @Configuration
- @EnableAspectJAutoProxy
- @ComponentScan
和AnnotationConfigApplicationContext而不是SpringApplication。
服务:
package sample.aop.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
@Value("${name:World}")
private String name;
public String getHelloMessage() {
return "Hello " + this.name;
}
}
监视器看点:
package sample.aop.monitor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ServiceMonitor {
@AfterReturning("execution(* sample..*Service.*(..))")
public void logServiceAccess(JoinPoint joinPoint) {
System.out.println("Completed: " + joinPoint);
}
}
使用编译时织,看到在插件例如:https://github.com/avner-levy/minimal_spring_hibernate_maven_setup/blob/master/pom.xml
下面的注释和Spring的结合感谢Tobi上面的注释,config对我有用如/威利/埃里克:
类:
package com.abc
@Configurable
@Aspect
public class MyAspect {
@Autowired
protected SomeType someAutoWiredField;
}
XML:
<context:spring-configured />
<context:component-scan base-package="com.abc" />
春天开机使用@Autowired使用AspectJ我发现下面的方法。 在配置类添加方面:
@Configuration
@ComponentScan("com.kirillch.eqrul")
public class AspectConfig {
@Bean
public EmailAspect theAspect() {
EmailAspect aspect = Aspects.aspectOf(EmailAspect.class);
return aspect;
}
}
然后你就可以成功地自动装配您服务您的切面类:
@Aspect
public class EmailAspect {
@Autowired
EmailService emailService;
你能还加上'@ Service'旁边'@ Aspect'? – 2012-03-09 12:13:21
它仍然是空的,但我现在收到的信息:预实例中org.s[email protected]76faf7d6单身:定义豆[...,SyncLoggingAspect在日志 – mogronalol 2012-03-09 12:20:31
你尝试加入的二传手SimpleEmailSender ?? – Rocky 2012-03-09 12:38:49