Java @Autowire 没有预先注入 Spring @Bean 配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18865037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@Autowire not preperly injected with Spring @Bean configuration
提问by Yves Nicolas
I am practising on spring-social and it seems that the userConnectionRepository is not properly autowired in the following code when I do a "Run as Junit Test" in Eclipse. I get a Null pointer exception on the usersConnectionRepository when creating a new FacebookOffLine although breakpoints put in the @Bean java creation code shows that they seem to be properly created. Thanks in advance,
我正在 spring-social 上练习,当我在 Eclipse 中执行“Run as Junit Test”时,userConnectionRepository 似乎没有在以下代码中正确自动装配。在创建新的 FacebookOffLine 时,我在 usersConnectionRepository 上收到空指针异常,尽管 @Bean java 创建代码中的断点显示它们似乎已正确创建。提前致谢,
public class FacebookOffline {
private Facebook fb;
@Autowired
private UsersConnectionRepository usersConnectionRepository;
public FacebookOffline(User user) {
super();
ConnectionRepository cr = usersConnectionRepository.createConnectionRepository(user.getId());
fb = cr.getPrimaryConnection(Facebook.class).getApi();
}
}
Here is the test code :
这是测试代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
org.springframework.social.quickstart.config.MainConfig.class,
org.springframework.social.quickstart.config.SocialConfig.class })
public class FacebookOfflineTest {
@Test
public void test1() {
FacebookOffline essai = new FacebookOffline(new User("yves"));
And the Spring configuration classes adapted from Keith Donald Quick Start Sample :
以及改编自 Keith Donald Quick Start Sample 的 Spring 配置类:
@Configuration
@ComponentScan(basePackages = "org.springframework.social.quickstart", excludeFilters = { @Filter(Configuration.class) })
@PropertySource("classpath:org/springframework/social/quickstart/config/application.properties")
public class MainConfig {
@Bean
public DataSource datasource() {
DriverManagerDataSource toReturn = new DriverManagerDataSource("jdbc:mysql://localhost:3306/spring_social");
toReturn.setDriverClassName("com.mysql.jdbc.Driver");
toReturn.setUsername("spring");
toReturn.setPassword("spring");
return toReturn;
}
}
@Configuration
public class SocialConfig {
@Inject
private Environment environment;
@Inject
private DataSource dataSource;
@Bean
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new FacebookConnectionFactory(environment
.getProperty("facebook.clientId"), environment
.getProperty("facebook.clientSecret")));
return registry;
}
@Bean
public UsersConnectionRepository usersConnectionRepository() {
JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(
dataSource, connectionFactoryLocator(), Encryptors.noOpText());
return repository;
}
}
采纳答案by M. Deinum
Actually there are 2 problems here.
其实这里有2个问题。
- Spring cannot autowire beans it doesn't control (i.e. created with new)
- Dependencies aren't available in the constructor (an object instance is needed before it can be injected)
- Spring 不能自动装配它不受控制的 bean(即用 new 创建)
- 依赖项在构造函数中不可用(在注入之前需要一个对象实例)
The first one can be mitigated by letting spring manage an instance of FacebookOffline (or if you need multiple instances make the bean request or session scoped).
第一个可以通过让 spring 管理 FacebookOffline 的实例来缓解(或者如果您需要多个实例使 bean 请求或会话范围限定)。
The second is a bit harder but can probaly solved by using a method annotated with @PostConstruct
(or by implementing InitializingBean
from spring).
第二个有点难,但可以通过使用注释的方法@PostConstruct
(或InitializingBean
从 spring实现)来解决。
回答by chrylis -cautiouslyoptimistic-
Spring can't autowire fields on an instance you create via new
since it doesn't know about it. Declare a bean of type FacebookOffline
instead.
Spring 无法在您创建的实例上自动装配字段,new
因为它不知道它。FacebookOffline
改为声明一个 bean 类型。
回答by TheKojuEffect
You did
你做到了
FacebookOffline essai = new FacebookOffline(new User("yves"));
That means, Spring isn't managing this essai
instance and thus spring can't autowire any variables in the essai
.
这意味着,Spring 不管理此essai
实例,因此 spring 无法自动装配essai
.
You'll have to create bean of FacebookOffline
in SocialConfig
.
你必须创建 bean of FacebookOffline
in SocialConfig
。
Then you can have
然后你可以有
/* ... */
public class FacebookOfflineTest {
@Autowired
ApplicationContext context;
@Test
public void test1() {
FacebookOffline essai = context.getBean(FacebookOffline.class);
OR
或者
/* ... */
public class FacebookOfflineTest {
@Autowired
FacebookOffline essai;
@Test
public void test1() {
// You can use essai now
Also, you'll need to update FacebookOffline
as Dependencies ain't available in constructor.
此外,您需要更新,FacebookOffline
因为依赖项在构造函数中不可用。
public class FacebookOffline {
private Facebook fb;
@Autowired
private UsersConnectionRepository usersConnectionRepository;
public FacebookOffline(User user) {
super();
}
@PostConstruct
void loadFacebook() {
ConnectionRepository cr = usersConnectionRepository.createConnectionRepository(user.getId());
fb = cr.getPrimaryConnection(Facebook.class).getApi();
}
}