Saya telah memulai proyek saya dengan membuat entitas, layanan, dan pengujian JUnit untuk layanan menggunakan Spring dan Hibernate. Semua ini bekerja dengan baik. Kemudian saya telah menambahkan spring-mvc untuk membuat aplikasi web ini menggunakan banyak tutorial langkah demi langkah yang berbeda, tetapi ketika saya mencoba membuat Pengontrol dengan anotasi @Autowired, saya mendapatkan kesalahan dari Glassfish selama penerapan. Saya rasa untuk beberapa alasan Spring tidak melihat layanan saya, tetapi setelah banyak upaya saya masih tidak bisa mengatasinya.
Tes untuk layanan dengan
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml"})
dan
@Autowired
MailManager mailManager;
bekerja dengan baik.
Pengontrol tanpa @Autowired juga, saya dapat membuka proyek saya di browser web tanpa masalah.
/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 <[email protected]>
*/
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";
}
}
Kesalahan:
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)}
Maaf untuk banyak kode, tapi saya tidak tahu apa yang bisa menyebabkan kesalahan itu lagi.
Ditambahkan
Saya telah membuat antarmuka:
@Component
public interface IMailManager {
alat tambahan:
@Component
@Transactional
public class MailManager extends AbstractManager implements IMailManager {
dan mengubah autowired:
@Autowired
public IMailManager mailManager;
Tapi masih ada kesalahan (juga ketika saya mencoba dengan @Qualifier)
..Tidak bisa autowire field: public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager ...
Saya sudah mencoba dengan kombinasi yang berbeda dari @Component dan @Transactional juga.
Bukankah saya harus menyertakan beans.xml di web.xml entah bagaimana?
sumber
MailManagerInterface
danIMailManager
? :)IMailManager
dimana - mana.<import resource="classpath:/beans.xml"/>
kemvc-dispatcher-servlet.xml
Jawaban:
Anda harus memasang antarmuka otomatis,
AbstractManager
bukan kelasMailManager
. Jika Anda memiliki implementasi yang berbedaAbstractManager
Anda dapat menulis@Component("mailService")
dan kemudian@Autowired @Qualifier("mailService")
menggabungkan ke autowire kelas tertentu.Hal ini disebabkan oleh fakta bahwa Spring membuat dan menggunakan objek proxy berdasarkan antarmuka.
sumber
@Autowired AbstractManager[] abstractManagers
itu yang berisi semua implementasinya.MailManager
?@Service
kelas yang menerapkan antarmuka yang sama. Keduanya berada@Autowired
di kelas lain. Awalnya itu menyebabkan masalah yang sama seperti postingan asli ketika saya menggunakan tipe kelas tertentu. Mengikuti jawaban ini, saya mengubah menggunakan jenis Antarmuka dengan@Qualifier("myServiceA")
dan@Qualifier("myServiceB")
, dan masalah teratasi. Terima kasih!Saya mengalami ini karena pengujian saya tidak dalam paket yang sama dengan komponen saya. (Saya telah mengganti nama paket komponen saya, tetapi bukan paket pengujian saya.) Dan saya menggunakan
@ComponentScan
di@Configuration
kelas pengujian saya , jadi pengujian saya tidak menemukan komponen yang mereka andalkan.Jadi, periksa kembali jika Anda mendapatkan kesalahan ini.
sumber
@Configuration
kelas darisrc/main
dalamsrc/test
?Masalahnya adalah bahwa konteks aplikasi dan konteks aplikasi web terdaftar di WebApplicationContext selama startup server. Saat Anda menjalankan pengujian, Anda harus secara eksplisit memberi tahu konteks mana yang akan dimuat.
Coba ini:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})
sumber
@SpringBootApplication(scanBasePackages = { "com.package.one", "com.package.two" })
Menghabiskan banyak waktu saya dengan ini! Salahku! Kemudian menemukan bahwa kelas tempat saya mendeklarasikan anotasi
Service
atauComponent
bertipe abstrak. Telah mengaktifkan log debug di Springframework tetapi tidak ada petunjuk yang diterima. Silakan periksa apakah kelasnya berjenis abstrak. Jika kemudian, aturan dasar yang diterapkan, tidak dapat membuat instance kelas abstrak.sumber
Saya menghadapi masalah yang sama saat memasang kabel otomatis kelas dari salah satu file jar saya. Saya memperbaiki masalah ini dengan menggunakan anotasi @Lazy:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @Autowired @Lazy private IGalaxyCommand iGalaxyCommand;
sumber
Dapatkah Anda mencoba memberi anotasi hanya pada implementasi konkret Anda
@Component
? Mungkin jawaban berikut bisa membantu. Ini masalah yang serupa. Saya biasanya meletakkan anotasi Spring di kelas implementasi.https://stackoverflow.com/a/10322456/2619091
sumber
Cara yang benar adalah dengan autowire AbstractManager, seperti yang disarankan Max, tetapi ini akan bekerja dengan baik juga.
@Autowired @Qualifier(value="mailService") public MailManager mailManager;
dan
@Component("mailService") @Transactional public class MailManager extends AbstractManager { }
sumber
Saya berlari ke ini baru-baru ini, dan ternyata, saya telah mengimpor anotasi yang salah di kelas layanan saya. Netbeans memiliki opsi untuk menyembunyikan pernyataan impor, itulah mengapa saya tidak melihatnya selama beberapa waktu.
Saya telah menggunakan,
@org.jvnet.hk2.annotations.Service
bukan@org.springframework.stereotype.Service
.sumber
lihat lebih banyak url ini:
http://www.baeldung.com/spring-nosuchbeandefinitionexception
sumber
<context:component-scan base-package="com.*" />
masalah yang sama tiba, saya menyelesaikannya dengan menjaga anotasi tetap utuh dan di dispatcher servlet :: menjaga pemindaian paket dasar karena
com.*.
ini berfungsi untuk saya.sumber
Ini dapat membantu Anda:
Saya memiliki pengecualian yang sama dalam proyek saya. Setelah mencari sementara saya menemukan bahwa saya kehilangan anotasi @Service ke kelas tempat saya mengimplementasikan antarmuka yang saya ingin @Autowired.
Dalam kode Anda, Anda dapat menambahkan anotasi @Service ke kelas MailManager.
@Transactional @Service public class MailManager extends AbstractManager implements IMailManager {
sumber
@Service
penjelasan mengandung@Component
. Memiliki keduanya itu mubazir.Daripada @Autowire MailManager mailManager, Anda dapat membuat tiruan kacang seperti yang diberikan di bawah ini:
import org.springframework.boot.test.mock.mockito.MockBean; :: :: @MockBean MailManager mailManager;
Selain itu, Anda dapat mengonfigurasi
@MockBean MailManager mailManager;
secara terpisah di@SpringBootConfiguration
kelas dan menginisialisasi seperti di bawah ini:@Autowire MailManager mailManager
sumber
Menghadapi masalah yang sama di aplikasi boot musim semi saya meskipun saya mengaktifkan pemindaian khusus paket saya seperti
@SpringBootApplication(scanBasePackages={"com.*"})
Namun, masalah tersebut diselesaikan dengan menyediakan
@ComponentScan({"com.*"})
di kelas Aplikasi saya.sumber
Dugaan saya adalah di sini
<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>
semua anotasi pertama-tama dinonaktifkan oleh use-default-filters = "false" dan kemudian hanya anotasi @Controller yang diaktifkan. Karenanya, anotasi @Component Anda tidak diaktifkan.
sumber
Jika Anda menguji pengontrol Anda. Jangan lupa untuk menggunakan @WebAppConfiguration di kelas pengujian Anda.
sumber
Saya mengalami ini terjadi karena saya menambahkan ketergantungan autowired ke kelas layanan saya tetapi lupa menambahkannya ke tiruan yang disuntikkan dalam pengujian unit layanan saya.
Pengecualian pengujian unit tampaknya melaporkan masalah di kelas layanan ketika masalah sebenarnya ada di pengujian unit. Dalam retrospeksi, pesan kesalahan memberitahu saya apa masalahnya.
sumber
Solusi yang berhasil bagi saya adalah menambahkan semua kelas yang relevan ke
@ContextConfiguration
anotasi untuk kelas pengujian.Kelas yang akan diuji
MyClass.java
, memiliki dua komponen yang dipasang secara otomatis:AutowireA
danAutowireB
. Ini perbaikan saya.@ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class}) public class MyClassTest { ... }
sumber