Autowiring in Spring bean (@Component) created with new keyword
Asked Answered
L

2

10

I have two spring beans as follows:

@Component("A")
@Scope("prototype")
public class A extends TimerTask {

    @Autowired
    private CampaignDao campaignDao;
    @Autowired
    private CampaignManager campManger;
    A(){
        init_A();
       }
    }

I have to make a new object of A with new keyword, due to a legacy code

@Component("B")
@Scope("prototype")
public class B{
     public void test(){
       A a = new A();
     }
}

when Running -> the spring beans in the class A are null, can i create a new instance of the spring bean A and still use autowiring in it ?

Lefty answered 12/6, 2012 at 12:54 Comment(1)
have you defined campaignDao and campManger in your Spring bean definitions file?Fictitious
I
16

Yours component "A" is not created by Spring container, thus, dependencies are not injected. However, if you need to support some legacy code (as I understand from your question), you can use @Configurable annotation and build/compile time weaving:

@Configurable(autowire = Autowire.BY_TYPE)
public class A extends TimerTask {
  // (...)
}

Then, Spring will inject autowired dependencies to component A, no matter if it's instantiated by container itself, or if it's instantiated in some legacy code by new.

For example, to set up build-time weaving with maven plugin you have to:

  1. Add <context:spring-configured/> to the Spring application context
  2. Configure Maven AspectJ plugin:

in the build plugins section:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>aspectj-maven-plugin</artifactId>
      <version>1.4</version>
      <configuration>
        <complianceLevel>1.6</complianceLevel>
        <encoding>UTF-8</encoding>
        <aspectLibraries>
          <aspectLibrary>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
          </aspectLibrary>
        </aspectLibraries>
        <!-- 
          Xlint set to warning alleviate some issues, such as SPR-6819. 
          Please consider it as optional.
          https://jira.springsource.org/browse/SPR-6819
        -->
        <Xlint>warning</Xlint>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>test-compile</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

...and the dependencies section:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>3.1.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.6.11</version>
</dependency>

Please consult Spring reference for more details: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable

Ize answered 12/6, 2012 at 13:47 Comment(10)
the A class is instantiated in other classes using the keyword new, can i still make autowiring in class A after creating a new object using keyword new ?Lefty
Yes - please take a look at the chapter in the Spring reference documentation I posted. It is possible with @Configurable annotation and compile / load time weaving.Ize
well, i made the spring bean that's created by new keyword @Configurable(autowire = Autowire.BY_TYPE) and still getting same behavior, so what am i missing ? and what do you mean by compile / load time weavingLefty
For this to work, annotated types must be woven at either compile time (use ant or maven plugin) or at runtime (see static.springsource.org/spring/docs/current/…). I've updated answer to include sample configuration for build-time weaving - this is the one I use.Ize
it still getting the same behavior when create bean by new Keyword the '@Autowired' field still null.so what am i missing ?. @Piotrek DeLefty
Do you use maven or ant? If so, did you configure the aspectj plugin?Ize
yes , i use maven. i add the dependency and plugin using your answer @Piotrek DeLefty
Have you also added <context:spring-configured/> to your Spring context? If so, please try to make full build with clean and try again.Ize
let us continue this discussion in chatIze
Where is spring context file?Coot
B
2

Because you are creating the object of class A yourself using new operator, you are not getting the autowired fields in that object and finding them null. Try to get the bean from spring container.

Hope this helps you. Cheers.

Blaise answered 12/6, 2012 at 13:6 Comment(2)
i have to create a new object from A, can i create a new object from A and still able to autowire in ALefty
No its not possible. Instead of that you should declare your bean A as prototype. So that everytime you request its object it will give you a fresh object initialized with its properties. And the autowired fields in that object will work for your. :-)Blaise

© 2022 - 2024 — McMap. All rights reserved.