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 ?

abdelhady
  • 560
  • 5
  • 10
  • 23

2 Answers2

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

omnomnom
  • 8,911
  • 4
  • 41
  • 50
  • 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 ? – abdelhady Jun 19 '12 at 15:02
  • 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. – omnomnom Jun 19 '12 at 15:55
  • 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 weaving – abdelhady Jun 19 '12 at 16:00
  • For this to work, annotated types must be woven at either compile time (use ant or maven plugin) or at runtime (see http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw). I've updated answer to include sample configuration for build-time weaving - this is the one I use. – omnomnom Jun 19 '12 at 20:09
  • it still getting the same behavior when create bean by new Keyword the '@Autowired' field still null.so what am i missing ?. @Piotrek De – abdelhady Jun 20 '12 at 11:12
  • Do you use maven or ant? If so, did you configure the aspectj plugin? – omnomnom Jun 20 '12 at 11:27
  • yes , i use maven. i add the dependency and plugin using your answer @Piotrek De – abdelhady Jun 20 '12 at 11:36
  • Have you also added to your Spring context? If so, please try to make full build with clean and try again. – omnomnom Jun 20 '12 at 11:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/12799/discussion-between-piotrek-de-and-abdelhady) – omnomnom Jun 20 '12 at 11:51
  • Where is spring context file? – Fazlan Ahamed Nov 24 '20 at 16:36
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.

Japan Trivedi
  • 4,445
  • 2
  • 23
  • 44
  • i have to create a new object from A, can i create a new object from A and still able to autowire in A – abdelhady Jun 19 '12 at 15:05
  • 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. :-) – Japan Trivedi Jun 20 '12 at 04:56