I have studied many other StackOverflow posts on Spring autowire issues. This question is not so simple as "don't expect @Autowire to work on an object you new
".
I have a library that constructs objects from class names. The object classes must extend class F. The library is not built with Spring. It accepts a class loader for resolving the class names. It is doing this:
Class<?> someClass = Class.forName(className, true, classLoader);
if (F.class.isAssignableFrom(someClass)) {
Class<? extends F> fClass = (Class<? extends F>) someClass;
Constructor constructor = fClass.getConstructor(FMap.class, Object.class);
F fobject = (F) constructor.newInstance(parameterMap, applicationContext);
...
The library allows some context to be passed in. Here I provide the Spring ApplicationContext. A particular subclass of F has code like this in its constructor:
ApplicationContext applicationContext = (ApplicationContext)context;
X xbean = (X)applicationContext.getBean("xbean");
S sobject = new S(xbean);
Class X is defined like this:
@Component
public class X {
private final Y ybean;
@Autowired
public X(Y ybean) {
this.ybean = ybean;
}
...
Class Y is another @Component.
The sobject
is able to call a method in the xbean
(xbean is not null), but the ybean
is null. Why?
I thought that Spring constructed and wired up the @Components at application start time. I expected that using an object from ApplicationContext would give me a completely built and wired up object.
Updates 06/03/2020 I added an @PostConstruct as suggested in the first answer. That showed that the object is getting constructed early in the life of the application.
I tried disabling spring.devtools.restart.enabled
with no change in behavior.
I tried disabling spring.main.lazy-initialization
with no change in behavior.
I removed spring-boot-devtools from my build.gradle with no change in behavior. However, the class loader being reported when the F objects and the Y bean are constructed is sun.misc.Launcher$AppClassLoader
We are running org.springframework.boot:spring-boot-starter-web:2.2.6.RELEASE.
Your class Y will only be autowired, when it is also present in Springs' application context. Verify that you actually have your component scan configured so that it picks up your Y component. you can quickly verify this by adding a post consturct snippet to Y.
@PostConstruct
void init() {
logger.info("Here I am");
}
If your logger prints nothing, Y is definitely not loaded into the application context.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.