Injecting Beans into a Class Outside the Spring Managed Context

Injecting beans into a class outside the Spring managed context

You can do this:

ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
someBeanNotCreatedBySpring,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);

You can use @Autowired and so on within YourClass to specify fields to be injected etc.

How do I inject spring beans into non-managed beans in a Spring boot console application?

I did not clone your project, just started to take a quick look at your POM in the browser. What immediately jumped at me was this:

Your Maven POM is wrong. You only preconfigure the AspectJ Maven Plugin in the pluginManagement section without ever actually declaring the plugin in the regular plugins section. I.e., the plugin is not going to be used during your build.

If after fixing that you are still having follow-up problems, I can take a second look.


Update: What I said before is true, but I also noticed some more oversights in your POM and test code:

  • You use a non-existent AspectJ Maven Plugin version.
  • For compile-time weaving, you need the AspectJ runtime aspectjrt on the classpath.
  • You need spring-tx on the dependency list, otherwise a class referred to by spring-aspects will not be found.
  • Your test expects a result different from the actual "ok".

Update 2: You can simply accept this pull request.

@Autowired or constructor inject non-managed classes into Spring context @Service for better testing

Option 1

If you don't want to turn your MyDao into a Spring-managed Bean, your simpler and probably best option is to instead create the MyService Spring-managed Bean programmatically instead of relying on @Service annotation. First, just remove @Service from MyService and adjust its constructor to accept MyDao:

public class MyService {

MyDao myDao;

public MyService(MyDao myDao) {
this.myDao = myDao;
}

public void foo() {
myDao.bar();
....
}
}

And now you just need to register a MyService bean using @Bean in a Configuration class as follows:

@Configuration
public class WhateverConfiguration {

@Bean
MyService myService() {
return new MyService(DaoProvider.getMyDao());
}
}


Option 2

If instead there is a possibility to make MyDao a Spring-managed Bean, then just keep your NonManagedSpringInjectionConfiguration as is:

@Configuration
public class NonManagedSpringInjectionConfiguration {

@Bean
MyDao getMyDao() {
return DaoProvider.getMyDao();
}
}

But then rely on constructor injection instead of on @Autowired. It makes MyService easier to unit test and also explicitly defines that MyDao is mandatory for MyService to work properly. In this case you would keep @Service and rely on Spring to instantiate it:

@Service
public class MyService {

MyDao myDao;

public MyService(MyDao myDao) {
this.myDao = myDao;
}

public void foo() {
myDao.bar();
....
}
}


Related Topics



Leave a reply



Submit