@Autowired
と@Service
の背後にある概念を理解するのに助けが必要です。 DAOを@Service
で定義し、コントローラーを@Autowired
で定義しましたが、すべて問題ないようですが、別のクラスで同じ@Autowired
を使用すると、機能しません。
例:
サービス
@Service
public class MyService {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource (DataSource myDataSource) {
this.jdbcTemplate = new JdbcTemplate(myDataSource);
}
public void testUpdate(){
jdbcTemplate.update("some query");
}
}
コントローラ
package com.springtest.mywork.controller;
@Controller
@RequestMapping(value = "/test.html")
public class MyController
{
@Autowired
MyService myService;
@RequestMapping(method = RequestMethod.GET)
public String test(Model model)
{
systemsService.testUpdate();
return "view/test";
}
}
上記はすべて正常に動作します。ただし、POJOでMyService
を使用したい場合は、機能しません。例:
package com.springtest.mywork.pojos;
public class MyPojo {
@Autowired
MyService myService;
public void testFromPojo () {
myService.someDataAccessMethod(); //myService is still null
}
}
Spring Config:
<beans>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<context:component-scan base-package="com.springtest.mywork" />
<bean id="dataSource" destroy-method="close" class="org.Apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb" />
<property name="username" value="hello" />
<property name="password" value="what" />
</bean>
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
</beans>
これは、POJOクラスがSpringコンテナによって管理されていないためです。
@Autowire
注釈がスプリングによって管理されているオブジェクトのみを動作します(つまり、春のコンテナによって作成されました)。
あなたの場合、サービスとコントローラーオブジェクトはSpringによって管理されていますが、POJOクラスはSpringによって管理されていないため、@Autowire
は期待される動作を生成していません。
私が気付いたもう1つの問題は、Springにこの目的のために特別に作成された@Service
アノテーションがある場合、DAOレイヤーで@Repository
アノテーションを使用していることです。
また、通常はコンテナの外部で作成する必要があるのはデータストレージ要素であるため、SpringがPOJOクラスを管理できるようにすることは望ましくありません。
POJOクラスの目的と、その中でservice
インスタンスが使用される理由を教えてください。
クラスパススキャンを使用する場合、管理するクラスをSpringに伝達する必要があります。これは、@Service
アノテーションとその関係(@Controller
、@Repository
など)を使用して行われます。
Beanに注釈を付けるためにnotを選択した場合は、dataSource
およびjdbcTemplate
で行ったように、構成で明示的に宣言する必要があります。
クラスに注釈を付けるということは、パッケージ内のそれらのクラスのみがSpringによって管理されることを意味します。これにより、パッケージ内のallクラスを管理しなくてもパッケージをスキャンできます。
これをapplicationContext.xmlファイルに含めます
<context:annotation-config />
これを実装して、POJOクラスでSpring管理のBeanを使用できます。
http://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html