我通过使用Spring和Hibernate为服务创建实体,服务和JUnit测试来启动我的项目。所有这一切都很棒。 然后我添加了spring-mvc来使用许多不同的分步教程来创建这个Web应用程序,但是当我尝试使用@Autowired注释创建Controller时,我在部署期间遇到来自Glassfish的错误。我想由于某些原因Spring没有看到我的服务,但经过多次尝试后我仍然无法处理它。
使用
测试服务@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml"})
和
@Autowired
MailManager mailManager;
正常运作。
没有@Autowired的控制器,我可以毫无困难地在网络浏览器中打开我的项目。
/src/main/resources/beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
<context:property-placeholder location="jdbc.properties" />
<context:component-scan base-package="pl.com.radzikowski.webmail">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!--<context:component-scan base-package="pl.com.radzikowski.webmail.service" />-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Persistance Unit Manager for persistance options managing -->
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<!-- Entity Manager Factory for creating/updating DB schema based on persistence files and entity classes -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="persistenceUnitName" value="WebMailPU"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--<property name="schemaUpdate" value="true" />-->
<property name="packagesToScan" value="pl.com.radzikowski.webmail.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
/webapp/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
/webapp/WEB-INF/mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
pl.com.radzikowski.webmail.service.AbstractManager
package pl.com.radzikowski.webmail.service;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Master Manager class providing basic fields for services.
* @author Maciej Radzikowski <maciej@radzikowski.com.pl>
*/
public class AbstractManager {
@Autowired
protected SessionFactory sessionFactory;
protected final Logger logger = Logger.getLogger(this.getClass());
}
pl.com.radzikowski.webmail.service.MailManager
package pl.com.radzikowski.webmail.service;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class MailManager extends AbstractManager {
// some methods...
}
pl.com.radzikowski.webmail.HomeController
package pl.com.radzikowski.webmail.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pl.com.radzikowski.webmail.service.MailManager;
@Controller
@RequestMapping("/")
public class HomeController {
@Autowired
public MailManager mailManager;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String homepage(ModelMap model) {
return "homepage";
}
}
错误:
SEVERE: Exception while loading the app
SEVERE: Undeployment failed for context /WebMail
SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
很抱歉有很多代码,但我不知道会导致该错误的原因。
加
我创建了界面:
@Component
public interface IMailManager {
添加了工具:
@Component
@Transactional
public class MailManager extends AbstractManager implements IMailManager {
并更改了自动装配:
@Autowired
public IMailManager mailManager;
但它仍然会引发错误(当我尝试使用@Qualifier时)
..无法自动装配字段:公开 pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager ...
我也试过@Component和@Transactional的不同组合。
我不应该以某种方式在web.xml中包含beans.xml吗?
答案 0 :(得分:63)
您应该自动加入接口AbstractManager
而不是类MailManager
。如果您有AbstractManager
的不同实现,则可以编写@Component("mailService")
然后@Autowired @Qualifier("mailService")
组合来自动跟踪特定类。
这是因为Spring根据接口创建并使用代理对象。
答案 1 :(得分:22)
我发生这种情况是因为我的测试与我的组件不在同一个包中。 (我已经重命名了我的组件包,但不是我的测试包。)我在我的测试@ComponentScan
课程中使用@Configuration
,所以我的测试没有找到他们所依赖的组件。
因此,如果您收到此错误,请仔细检查。
答案 2 :(得分:8)
事情是,在服务器启动期间,应用程序上下文和Web应用程序上下文都在WebApplicationContext中注册。运行测试时,必须明确指出要加载的上下文。
试试这个:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})
答案 3 :(得分:5)
我花了很多时间在这上面!我的错!后来发现我声明注释Service
或Component
的类是抽象类型。已在Springframework上启用调试日志但未收到任何提示。请检查类是否为抽象类型。如果那时,应用的基本规则不能实例化抽象类。
答案 4 :(得分:3)
正如Max建议的那样,正确的方法应该是自动装配AbstractManager,但这也应该可以正常工作。
@Autowired
@Qualifier(value="mailService")
public MailManager mailManager;
和
@Component("mailService")
@Transactional
public class MailManager extends AbstractManager {
}
答案 5 :(得分:3)
您可以尝试使用@Component
仅注释具体实现吗?也许以下answer可以提供帮助。这是一个类似的问题。我通常将Spring注释放在实现类中。
答案 6 :(得分:2)
我最近遇到了这个问题,事实证明,我在服务类中导入了错误的注释。 Netbeans可以选择隐藏import语句,这就是我一段时间没有看到它的原因。
我使用@org.jvnet.hk2.annotations.Service
代替@org.springframework.stereotype.Service
。
答案 7 :(得分:1)
这可能会对您有所帮助:
我的项目中有相同的例外。搜索之后,我发现我错过了@Service注释到我正在实现我想要@Autowired的接口的类。
在您的代码中,您可以将@Service注释添加到MailManager类。
@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {
答案 8 :(得分:1)
从我的jar文件之一自动连接类时,我遇到了同样的问题。 我通过使用@Lazy批注解决了该问题:
ST_GeomFromGeoJSON()
答案 9 :(得分:1)
查看更多此网址:
http://www.baeldung.com/spring-nosuchbeandefinitionexception
答案 10 :(得分:0)
如果您正在测试控制器。 不要忘记在测试类上使用@WebAppConfiguration。
答案 11 :(得分:0)
<context:component-scan base-package="com.*" />
同样的问题到了,我通过保持注释完整并在调度程序 servlet 中解决了它::将基本包扫描保持为com.*.
这对我有用。
答案 12 :(得分:0)
之所以发生这种情况,是因为我在我的服务类中添加了自动关联,但是却忘记了将其添加到服务单元测试中的注入模拟中。
当问题实际上在单元测试中时,单元测试异常似乎报告了服务类中的问题。回想起来,错误消息告诉我问题出在哪里。
答案 13 :(得分:0)
您可以模拟@@ bean来代替@Autowire MailManager mailManager:
import org.springframework.boot.test.mock.mockito.MockBean;
::
::
@MockBean MailManager mailManager;
此外,您可以在@MockBean MailManager mailManager;
类中分别配置@SpringBootConfiguration
并按如下所示进行初始化:
@Autowire MailManager mailManager
答案 14 :(得分:0)
我猜是在这里
<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
首先使用use-default-filters =&#34; false&#34;禁用所有注释。然后只启用@Controller注释。因此,未启用@Component注释。
答案 15 :(得分:0)
即使我启用了特定于软件包的扫描(如
),在spring boot应用程序中也遇到了相同的问题sysuse auto, clear
eststo clear
rename (weight mpg turn) mpg#, addnumber
forvalues i = 1 / 3 {
eststo: quietly reg price mpg`i'
local mpglist `mpglist' mpg`i' mpg
}
esttab, rename(`mpglist')
------------------------------------------------------------
(1) (2) (3)
price price price
------------------------------------------------------------
mpg 2.044*** -238.9*** 207.6**
(5.42) (-4.50) (2.76)
_cons -6.707 11253.1*** -2065.0
(-0.01) (9.61) (-0.69)
------------------------------------------------------------
N 74 74 74
------------------------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001
但是,通过在我的Application类中提供@SpringBootApplication(scanBasePackages={"com.*"})
解决了该问题。
答案 16 :(得分:0)
对我有用的解决方案是将所有相关类添加到测试类的@ContextConfiguration
批注中。
要测试的类MyClass.java
具有两个自动装配的组件:AutowireA
和AutowireB
。这是我的解决方法。
@ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class})
public class MyClassTest {
...
}
答案 17 :(得分:0)
我遇到了同样的问题, 使用以下步骤解决了问题:
@service
。@Repository
。→我们可以有效地使用@Service
、@Repository
和@Component
注解并且非常快地解决这个问题。