spring autowiring not working from a non-spring managed class

前端 未结 10 886
暗喜
暗喜 2020-12-03 06:43

I have a class (Class ABC) that\'s instantiated by calling the constructor. Class ABC in turn has a helper class (Class XYZ) injected using auto-wired.

Ours is a Sp

相关标签:
10条回答
  • 2020-12-03 07:25

    Spring has util class

     BeanUtils.instantiateClass(clazz)
     BeanUtils.instantiate(clazz)
    
     YouClass ins = BeanUtils.instantiate(YouClass.class)
    

    https://docs.spring.io/autorepo/docs/spring/4.0.2.RELEASE/javadoc-api/org/springframework/beans/BeanUtils.html

    0 讨论(0)
  • 2020-12-03 07:29

    You can use Spring's @Configurable annotation in the class you want to autowire other beans. Additionally, you will need to annotate any configuration bean with @EnableSpringConfigured so that Spring is aware of your configurable beans.

    @EnableSpringConfigured documentation

    public @interface EnableSpringConfigured Signals the current application context to apply dependency injection to non-managed classes that are instantiated outside of the Spring bean factory (typically classes annotated with the @Configurable annotation). Similar to functionality found in Spring's XML element. Often used in conjunction with @EnableLoadTimeWeaving.

    @Configurable(autowire = Autowire.BY_TYPE)
    public class ABC {
        @Autowire private XYZ xyz;
        ...
    }
    
    @Configuration
    @EnableSpringConfigured
    public class Application {
        ...
    }
    
    public class MyClass {
        public void doSomething() {
            ABC abc = new ABC(); // XYZ is successfully autowired
            ...
        }
    }
    
    0 讨论(0)
  • 2020-12-03 07:30

    For noobs like me who do basic Spring Boot and aren't familiar with the lingo:

    • Your Services, Repos etc are all Beans
    • You can get your Beans from the ApplicationContext

    Ashish's answer works for me, but this article provides a bit more explanation imo.

    If you don't know the name of the bean you want, try looking in this array:

    String[] names = context.getBeanDefinitionNames();
    

    If you're confused by the talk of 'component scan' and config files, it may help to know that the @SpringBootApplication annotation (which you might find near your main() method) implicitly calls @Configuration and @ComponentScan.

    This means all files in that package (declared at the top of the main class) are picked up by Spring, and any beans you want to add can be written alongside main()

    0 讨论(0)
  • 2020-12-03 07:31

    First question - yes you have null because class not initiated with spring Second question - I think you can use aspectj support http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-using-aspectj

    0 讨论(0)
  • 2020-12-03 07:32

    In short, yes, ABC is not getting injected with XYZ because Spring is not managing ABC. Spring can't configure objects that it doesn't know about.

    You could manage ABC by annotating it with @Service or @Component. Note that in order for Spring to pick up on these annotations, Spring must have auto-scanning turned on:

    <context:component-scan base-package="com.mypackage.awesomeproject" />
    
    0 讨论(0)
  • 2020-12-03 07:42

    Autowiring won't work because class ABC is not managed by Spring. You could make Spring manage ABC by using one of the @Component annotations (@Component, @Service, @Controller, etc) above the class definition, and then using context:component-scan in your application context XML, or go old school and just define the bean directly in your application context.

    If for some reason you can't make Spring manage class ABC, you can load the application context in ABC using something like:

    ApplicationContext context = new ClassPathXmlApplicationContext("path/to/applicationContext.xml");

    and then use:

    XYZ someXyz = (XYZ) context.getBean("MyXYZ");

    to manually set the bean value.

    0 讨论(0)
提交回复
热议问题