使用@Autowired绑定不在使用' new'启动的实例内部工作

时间:2014-09-03 03:40:31

标签: spring dependency-injection

在我的Web spring应用程序中,我创建了一个关键字new的实例,如下所示 在我的一个动作类中,存在以下方法。

public void process() { 

    MyBean b=new MyBean(); //initiated the instance with new  
    b.process();
}   

其他MyBean类

@Service
public class MyBean {  

@Autowired  
MyService service;  

public void process() { 
    service.execute(); // this service instance has not initialized by Spring DI :( .service object is null. 
}

Spring依赖注入不设置MyService实例。是因为我自己创建了MyBean的实例new而不是Spring?

5 个答案:

答案 0 :(得分:6)

如果您想以编程方式自动装配,可以使用:

private @Autowired AutowireCapableBeanFactory beanFactory;

public void process() {
   MyBean obj = new MyBean();
   beanFactory.autowireBean(obj);
   // obj will now have its dependencies autowired.
}

答案 1 :(得分:4)

是。它不是由Spring的DI设置的,因为使用new关键字创建的实例不是由Spring容器管理的。默认情况下,Spring仅为spring托管实例注入依赖项。因此,要解决此问题,您可以通过两种方式来解决此问题。首先是不要使用new并在@Autowired个实例上使用Mybean

其次是在@Configurable课程上使用MyBean。使用@Configurable注释弹簧将注入依赖关系,即使对于通过new关键字创建的对象也是如此。请记住在类路径中使用AspectJ jar并使用@configurable注释,因为Spring需要它们注入依赖项。

对于第二种方法,使用@Configurable(preConstruction = true)并将以下依赖项添加到您的pom.xml

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

您还需要通过AspectJ Compiler进行编译,以便生成的字节代码具有所需的功能。您应该使用以下条目来确保系统在编译时使用AspectJ Compiler。

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>1.6</source>
<target>1.6</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.6</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>false</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.11</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

答案 2 :(得分:3)

当你用new创建一个对象时,autowire \ inject不起作用......

作为解决方法,你可以试试这个:

创建MyBean的模板bean

<bean id="myBean" class="..." scope="prototype">
    <!-- collaborators and configuration for this bean go here -->
</bean>

以这种方式创建一个istance

context.getBean("myBean");

PROTOTYPE:这可以使单个bean定义包含任意数量的对象实例。

答案 3 :(得分:2)

在您的情况下,spring无法识别MyBean bean,因为您使用new运算符创建它。让spring初始化这个bean,然后你可以在MyBean内访问自动装配的bean。例如,

<bean id="myBean" class="your.package.MyBean"></bean>

在您的应用程序上下文中的上面的条目将在spring容器中创建MyBean。使用此对象,您可以访问其中编写的服务。

答案 4 :(得分:0)

另一种解决方案可以是使用@Component,如下所示:

@Component("myBean")
public class MyBean{  

    @Autowired  
    MyService service;  

    public void process(){ 

    service.execute(); // this service instance has not initialized by Spring DI :( .service object is null. 

    }
}

process()所在的班级,您可以像这样自动装配:

@Autowired
MyBean b

public void process(){  


  b.process();


}