我有一些自动注释的问题。我的应用程序如下所示:
这是控制器:
@Controller
public class MyController {
@Autowired
@Qualifier("someService")
private SomeService someService;
....
}
这是一个服务层:
public interface SomeService {
...
}
@Service
public class SomeServiceImpl implements SomeService{
@Autowired
@Qualifier("myDAO")
private MyDAO myDAO;
....
}
和DAO层:
public interface MyDAO{
....
}
@Repository
public class JDBCDAOImpl implements MyDAO {
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
....
}
这是app-service.xml文件:
....
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
<bean id="SomeService" class="com.service.SomeServiceImpl" />
<bean id="myDAO" class="com.db.JDBCDAOImpl" />
所以...当我启动一个web-app时,MyController自动正确(SomeServiceImpl类对象正确注入someService字段),但someService的myDAO feild为null值(未正确注入)。
你能帮我找个问题吗?
P.S。它很有意思,但是当我将myDAO中的“bean id”更改为另一个(例如myDAO2)时,系统会给我一个错误,因为bean myDAO不存在而无法进行注入。那么,Spring注射,但它在哪里?为什么它不能正常工作?
答案 0 :(得分:10)
我找到了解决方案。正如Javi所说(非常感谢你,Javi),我必须使用@Repository
和@Service
注释来注释DAO和服务层类。现在我试着这样写:
@Service("someService")
public class SomeServiceImpl implements SomeService{
@Autowired
@Qualifier("myDAO")
private MyDAO myDAO;
....
}
和
@Repository("myDAO")
public class JDBCDAOImpl implements MyDAO {
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
....
}
一切正常!!!
但是我仍然没有找到这个问题的答案:如果应用程序将更复杂,并且将具有更复杂的结构,其中@Repositore
和@Service
注释不是某些类的首选,如何正确注入bean,它位于较低级别(在类的字段中或在类的字段中)(当然,带有@Autowire
注释)?
答案 1 :(得分:4)
我想你需要<context:annotation-config />
。
答案 2 :(得分:2)
您可以使用
<context:component-scan base-package="PATH OF THE BASE PACKAGE"/>
配置.xml文件中的条目。此条目将扫描/读取java类中所有声明的类型和注释。
答案 3 :(得分:0)
重要点:
地址Bean在学生班级自动接线。 让我们看看如果在Address.java上应用@Component会发生什么。
CollegeApp.java:
+----+--------+------------+----------------+
| id | region | date1 | neareast_early |
+----+--------+------------+----------------+
| 1 | a | 2017-01-01 | |
| 2 | a | 2017-01-07 | 2017-01-01 |
| 3 | a | 2017-03-03 | 2017-01-07 |
| 4 | a | 2017-04-03 | 2017-03-03 |
| 5 | b | 2017-02-02 | |
| 6 | b | 2017-02-28 | 2017-02-02 |
+----+--------+------------+----------------+
我们希望将Elgin街与学生地址自动连线。
Address.java:
$( ".f_best" ).click(function(){
if ($('.productTable').has('.quality_class_a')) {
$('.productTable tr').has('.quality_class_a').toggle();
}
});
Student.java:
<dt class="uk-text-muted"></dt>
<dd class="quality_class_a">
<img src="/test/img/icons/A.png" alt="Kvaliteediklass: Parim (OEM vastav)"/>
<span class="tooltiptext">Kvaliteediklass: Parim (OEM vastav)</span>
</dd>
<b>Mann-filter CUK31003</b>
<br />
<span class="additionalInfo">
<!--<b>Lisainfo:</b> -->Pikkus (mm): 311 | Laius (mm): 220 | Kõrgus (mm): 31 | Filtritüüp: Aktiivsöefilter<span class="264289555_277655395_d"></span>
</span>
</td>
<td class="stock-list-price">
<table class="stock-list-category">
<tr class="stock-list-category-item green-tr " style="display: table-row!important;">
<td>
POL02
</td>
<td>L 11 aug </td>
<td class="price ">
26,91€
</td>
</tr>
</table>
</td>
</tr>
输出:-名称:null年龄:0地址:null //地址此处未自动接线。
要解决此问题,请仅按以下方式更改Address.java:
Address.java:
package com.myTest
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.bean.Address;
import com.bean.Student;
//Component scanning will for only those classes
//which is defined as @Component. But, all the class should not use
//@Component always even if the class is enabled with auto
//component scanning, specially the class which is Autowired
//Or which is a property of another class
@Configuration
@ComponentScan(basePackages={"com.bean"})
public class CollegeApp {
@Bean
public Address getAddress(){
return new Address("Elgin street");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(CollegeApp.class);
Student student=context.getBean(Student.class);
System.out.println(student.toString());
context.close();
}
}
输出:- 名称:无年龄:0地址:埃尔金街
答案 4 :(得分:0)
您应该在spring-config.xml
中加入XML代码的这一部分:
<context:component-scan base-package="Fully.Qualified.Package.Name" />
但是您应该知道<context:annotation-config>
与<context:component-scan>
之间的区别,因为大多数人都建议这两个:
1)两个标签之间的第一个大区别是:<context:annotation-config>
用于在应用程序上下文中已注册的bean中激活应用的注释。请注意,bean是否通过哪种机制注册都没有关系,例如使用<context:component-scan>
或在application-context.xml
文件本身中定义。
2)第二个差异是由第一个差异本身驱动的。它确实在上下文中注册了bean,并且还扫描了bean内部的注释并激活它们。所以<context:component-scan>
;做<context:annotation-config>
的工作,但是它还会扫描软件包并在应用程序上下文中注册Bean。
答案 5 :(得分:0)
有两个原因。
未对注入的对象进行注释或未使用正确的@ Service / @ Component / @ Repository注释对服务进行注释时。
确定了第1点后,接下来请检查带注释的服务类的类包是否包含在主类中的spring boot应用程序的类路径中。您可以使用以下注释。
@SpringBootApplication(scanBasePackages = { “ com.ie.efgh.somepackage”,“ com.ie.abcd.someotherpackage”})
这样做是要告诉spring在类加载期间检查类的包。
答案 6 :(得分:-2)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Specifying base package of the Components like Controller, Service,
DAO -->
<context:component-scan base-package="com.jwt" />
<!-- Getting Database properties -->
<context:property-placeholder location="classpath:application.properties" />
<!-- DataSource -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="dataSource">
<property name="driverClassName" value="${database.driver}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.user}"></property>
<property name="password" value="${database.password}"></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
</beans>