BeanNotOfRequiredTypeException aufgrund von automatisch verknüpften Feldern

Lesezeit: 11 Minuten

Benutzer-Avatar
Walknut

Ich bin immer noch neu bei Spring MVC und beim Erstellen meines Testprojekts habe ich diese Nachricht von Tomcat-Protokollen erhalten:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'divisionController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:307)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    ...
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:360)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

Ich habe zwei Rollendienste für Benutzer und Administrator mit ihren Schnittstellen:

package employee.service;

import employee.model.EmployeeDiv;
import employee.model.EmployeeInfo;
import employee.model.UserInfo;

import java.util.List;

/**
 *
 * @author serge
 */

public interface AdminService extends UserService {

     //  !!!! for register & udate of Employee use String type birthday !!!!

    /*
     * Employee
     */
    public EmployeeInfo registerEmployee(EmployeeInfo employeeInfo);

    public EmployeeInfo updateEmployee(EmployeeInfo employeeInfo);

    public EmployeeInfo findEmployeeByID(Integer id);   

    /*
     * Division
     */
    public EmployeeDiv registerDivision(EmployeeDiv division);

    public EmployeeDiv updateDivision(EmployeeDiv division);

    public List<EmployeeDiv> findAllDivisions();

    public List<EmployeeDiv> findDivisionsByName(EmployeeDiv division);

    public EmployeeDiv findDivisionsById(Integer id);

    /*
     * Login
     */
    public UserInfo registerUser(UserInfo user);

    public UserInfo updateUser(UserInfo user);

    public List<UserInfo> findAllUsesrs();

    public List<UserInfo> findUsesrByLogin(UserInfo user);

    public UserInfo findUsesrById(Integer id);
}

Dies ist AdminServiceImpl:

package employee.service.impl;

import employee.DAO.EmployeeDivDAO;
import employee.DAO.EmployeeInfoDAO;
import employee.DAO.UserDAO;
import employee.model.EmployeeDiv;
import employee.model.EmployeeInfo;
import employee.model.UserInfo;
import employee.service.AdminService;
import employee.validation.ParsingDate;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author serge
 *
 * Admin level
 *
 * Service for processing employee, divisions, userslogin
 */

//@Repository("adminService")
@Service("adminService")
@Transactional
public class AdminServiceImpl extends UserServiceImpl implements AdminService {

    protected static Logger adminLogger = Logger.getLogger("service");
    private EmployeeDivDAO emplDivDAO;
    private UserDAO userDAO;
    private EmployeeInfoDAO emplInfoDAO;

    @Autowired
    @Override
    public void setEmployeeDao(EmployeeInfoDAO emplInfoDAO) {
        this.emplInfoDAO = emplInfoDAO;
    }

    @Autowired
    public void setEmployeeDao(EmployeeDivDAO emplDivDAO) {
        this.emplDivDAO = emplDivDAO;
    }

    @Autowired
    public void setUserDao(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public AdminServiceImpl() {

        initTestEmployee();
    }

    /**
     * Initialize EmployeeInfo test
     */
    @Transactional
    @Secured("ROLE_ADMIN")
    private EmployeeInfo initTestEmployee() {

        adminLogger.debug("saving testEmployee");

        EmployeeInfo employeeInfo = new EmployeeInfo();
        ParsingDate date = new ParsingDate();
        employeeInfo.setFirstName("Petr");
        employeeInfo.setLastName("Ivanenko");
        employeeInfo.setEmpDiv("second");
        employeeInfo.setBirthdate(date.parseDate("1981-10-03"));
        employeeInfo.setSalary(3500);
        employeeInfo.setActive(true);

        return employeeInfo;
    }

    /**
     * registrating new Employee Information
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo registerEmployee(EmployeeInfo employeeInfo) {

        adminLogger.debug("registrating new Employee");

        try {

            emplInfoDAO.save(employeeInfo);

        } catch (NullPointerException e) {
        }
        return employeeInfo;
    }

    /**
     * updating Employee Information
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo updateEmployee(EmployeeInfo employeeInfo) {

        adminLogger.debug("updating Employee with id: " + employeeInfo.getId());
        try {

            emplInfoDAO.update(employeeInfo);

        } catch (NullPointerException e) {
        }
        return employeeInfo;
    }

    /**
     * Retrieving Employee Information by id 
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo findEmployeeByID(Integer id) {

        adminLogger.debug("Retrieving Employee with id= " + id);
        EmployeeInfo employeeInfo = new EmployeeInfo();
        employeeInfo.setId(id);
        emplInfoDAO.find(employeeInfo);
        return employeeInfo;
    }

    /**
     * registrating new Employee Division
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv registerDivision(EmployeeDiv division) {

        adminLogger.debug("registrating new Division");
        try {

            emplDivDAO.save(division);

        } catch (NullPointerException e) {
        }
        return division;
    }

    /**
     * updating Employee Division
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv updateDivision(EmployeeDiv division) {

        adminLogger.debug("updating Division with id: " + division.getId());
        try {

            emplDivDAO.update(division);

        } catch (NullPointerException e) {
        }
        return division;
    }

    /**
     * Retrieving all Employee Divisions
     *
     * @return List of EmployeeDiv objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<EmployeeDiv> findAllDivisions() {

        adminLogger.debug("Retrieving all divisions");
        return emplDivDAO.findAll();
    }

    /**
     * Retrieving all Employee Divisions by name
     *
     * @return List of EmployeeDiv objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<EmployeeDiv> findDivisionsByName(EmployeeDiv division) {
        String empDiv = "empDiv";

        adminLogger.debug("Retrieving Divisions by name: " + division.getEmpDiv());
        return emplDivDAO.findAllByParam(empDiv, division.getEmpDiv());
    }

     /**
     * Retrieving Employee Divisions by id 
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv findDivisionsById(Integer id) {

        adminLogger.debug("Retrieving Division with id= " + id);
        EmployeeDiv employeeDiv = new EmployeeDiv();
        employeeDiv.setId(id);
        emplInfoDAO.find(employeeDiv);
        return employeeDiv;
    }

    /**
     * registrating new User Information
     *
     * @return UserInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo registerUser(UserInfo user) {

        adminLogger.debug("registrating new User");
        try {

            userDAO.save(user);

        } catch (NullPointerException e) {
        }
        return user;
    }

    /**
     * updating new User Information
     *
     * @return UserInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo updateUser(UserInfo user) {

        adminLogger.debug("updating User with id: " + user.getId());
        try {

            userDAO.update(user);

        } catch (NullPointerException e) {
        }
        return user;
    }

    /**
     * retriviting all Users 
     *
     * @return List of UserInfo objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<UserInfo> findAllUsesrs() {

        adminLogger.debug("Retrieving all Users");
        return userDAO.findAll();
    }

    /**
     * retriving all Users by login
     *
     * @return List of UserInfo objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<UserInfo> findUsesrByLogin(UserInfo user) {
        String login = "login";

        adminLogger.debug("Retrieving User with login: " + login);
        return userDAO.findAllByParam(login, user.getLogin());
    }

    /**
     * Retrieving Employee Divisions by id 
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo findUsesrById(Integer id) {

        adminLogger.debug("Retrieving Division with id= " + id);
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        emplInfoDAO.find(userInfo);
        return userInfo;
    }
}

Dies ist applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <!-- Activates annotations -->

    <context:annotation-config />

    <!-- Scans for annotated components in base-package-->

    <context:component-scan base-package="employee" />

    <bean class="employee.service.impl.AdminServiceImpl"/>
    <bean class="employee.service.impl.UserServiceImpl"/>
    <!--bean class="employee.DAO.impl.EmployeeInfoDAOImpl"/>
    <bean class="employee.DAO.impl.EmployeeDivDAOImpl"/>
    <bean class="employee.DAO.impl.UserDAOImpl"/-->

    <!-- for Spring Jackson JSON support  -->

    <mvc:annotation-driven/>

    <!-- Shared Hibernate SessionFactory in a Spring application context. -->

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>

        <!--property name="dataSource">
            <ref bean="dataSource"/>
        </property-->

        <property name="annotatedClasses">
            <list>
                <value>employee.model.UserInfo</value>
                <value>employee.model.EmployeeInfo</value>
                <value>employee.model.EmployeeDiv</value>
            </list>
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- for database, imports the properties from database.properties -->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <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>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:database.properties"/>
    </bean>
</beans>

Bitte sagen Sie mir, was das Problem mit diesem Bean-Namen ist, ich verstehe, dass es sich um ein AOP-Problem handelt:

Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]

wie kann ich es beheben?

Ich verwende AdminServiceImpl in Controllern:

package employee.controller;

import employee.model.EmployeeDiv;
import employee.service.impl.AdminServiceImpl;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;

/**
 * @author serge
 *
 * Handles and retrieves division related requests
 */
@Controller
@RequestMapping("/division")
public class DivisionController {

    protected static Logger logger = Logger.getLogger("controller");
    @Resource(name = "adminService")
    private AdminServiceImpl adminService;

    /**
     * Handles and retrieves a /WEB-INF/jsp/divisionpage.jsp
     *
     * containing all division
     *
     * @return the name of the JSP page
     */
    @RequestMapping(method = RequestMethod.GET)
    public String getAllPage(Model model) {
        logger.debug("Received request to show all division page");

        // Retrieve all division and attach to model 
        model.addAttribute("division", adminService.findAllDivisions());
        return "divisionpage";
    } ....

Benutzer-Avatar
Tomasz Nurkiewicz

Irgendwo in Ihrem Code müssen Sie automatisch verdrahten AdminServiceImpl so was:

@Autowired
private AdminServiceImpl adminService;

Beide hängen kaum von der Schnittstelle ab:

@Autowired
private AdminService adminService;

oder aktivierte CGLIB-Proxys.

Ähnliche Probleme

  • Autowired Spring Bean ist kein Proxy
  • BeanNotOfRequiredTypeException bei Spring-Proxy-Cast auf einer Nicht-Singleton-Bean behoben?
  • Spring Error “Bean namens ‘x’ muss vom Typ sein [y]war aber eigentlich vom Typ [$Proxy]“ bei Jenkins
  • Die ursprüngliche Benutzeroberfläche geht bei der Spring AOP-Einführung verloren

  • @Serge: Sie können es selbst beheben, es ist ein häufiges Problem. Suchen Sie einfach nach automatisch verdrahteten Feldern des Typs AdminServiceImpl, ich bin mir ziemlich sicher, dass du welche hast. Dh suchen Sie nach Stellen, wo Sie tatsächlich verwenden AdminServiceImpl. Fallen Impl sich nur auf die Schnittstelle verlassen. Das ist es!

    – Tomasz Nurkiewicz

    24. Januar 2013 um 19:36 Uhr

  • Lassen Sie Impl fallen, um sich nur auf die Schnittstelle zu verlassen. Wenn ich dich verstehe? Ich muss die gesamte AdminServiceImpl-Nutzung durch AdminService ersetzen.

    – Walknut

    24. Januar 2013 um 19:40 Uhr

  • @Serge: in der Tat. Warum sollten Sie Klassen und Schnittstellen trennen, wenn Sie sich immer noch auf die Klasse verlassen? Der einzige Ort, wo ...Impl erscheint in der Klassendefinition, nirgendwo sonst.

    – Tomasz Nurkiewicz

    24. Januar 2013 um 19:42 Uhr

  • erzähl mir von “autowire”. Wie sollte ich Felder richtig automatisch verdrahten? Soll ich das im Interface machen oder habe ich alles richtig gemacht?

    – Walknut

    24. Januar 2013 um 19:53 Uhr

  • Die Schnittstelle anstelle der Implementierung verwendet und mit @Qualifier kommentiert, um die richtige Klasse zu erhalten. Mein Leben gerettet!

    – Christian F.

    23. Februar 2017 um 8:31 Uhr

Schnittstelle verwenden AdminService eher als die Geräte.

Dieser Fehler wird durch Annotation verursacht @Transactional, Spring macht einen Proxy für AdminService bei Runtime.

  • Oder wenn Sie hinzufügen @EnableTransactionManagement zur Konfiguration als Ergebnis @Transactional beginne zu arbeiten. Für mich

    – Borneo

    23. August 2019 um 5:25 Uhr


Benutzer-Avatar
Christian Altamirano Ayala

Wenn Ihre Serviceklasse eine Schnittstelle implementiert, nimmt spring standardmäßig einen Proxy von JDK, deshalb erhalten Sie diesen Fehler, sodass Sie dieses Problem lösen können, unabhängig davon, ob Sie @Autowired über die Schnittstelle verwenden oder die aktivieren CGLIB-Proxy.

Ich habe dieses Problem gelöst, indem ich den CGLIB-Proxy aktiviert habe Proxy-Zielklasse -Attribut in meinem Frühlingsanwendungskontext

<tx:annotation-driven proxy-target-class="true"
        transaction-manager="transactionManager" />

Benutzer-Avatar
Gräten

Ich habe viele ähnliche Fragen wie diese gefunden, als ich bei Google nach meinem Problem gesucht habe. In meinem Fall habe ich jedoch bereits eine Schnittstelle verwendet. Also dachte ich, das könnte für andere hilfreich sein:

Diese Ausnahme kann auch auftreten, wenn Sie zwei Beans mit demselben Namen haben!

In meinem Fall hatte ich eine zusätzliche Bean-Konfiguration in meiner applicationContext.xml. Das Problem trat auf, nachdem ich zwei Anwendungen zusammengeführt hatte. Der zweite definierte a @Resource und sein Member-Variablenname stimmte mit dem Bean-Namen der ersten oben erwähnten Anwendung überein. Natürlich passte die Bean-Konfiguration der ersten Anwendung nicht für das per eingebundene Bean @Resource durch die zweite Anwendung.

Benutzer-Avatar
Khairul Bashar Zitrone

Stellen Sie sicher, dass Sie ProxyTargetClass aktiviert haben, wie zum Beispiel:

@EnableTransactionManagement(proxyTargetClass = true)

Benutzer-Avatar
Rod Kimble

Ich habe das gleiche Problem, aber ich habe das Problem mit der folgenden Problemumgehung gelöst:

Bitte ersetzen Sie Ihre Implementierungsklasse durch Schnittstelle. Zum Beispiel:

class Abc
{
 @Autowire
 private Boy boy // remove @BoyImpl

.............
...................
}

Benutzer-Avatar
Jimmy

Bei einigen hatte ich dieses Problem auch @SpringBootTest Klassen, die Endpunkte getestet haben. Die Endpunkte hatten eine Abhängigkeit von einem DB-Dienst, der vorhanden ist @Transactional auf ein paar Methoden.

Wegen dem @TransactionalSpring fängt das ab und erstellt eine Proxy-Klasse, sodass Spock (oder junit) Schwierigkeiten haben würde, den richtigen Mock einzufügen.

Meine Problemumgehung bestand darin, den DB-Dienst um eine Ebene nach unten zu verschieben und einfache Spock-Tests um die mittlere Ebene herum durchzuführen, die davon nicht betroffen sind.

1140600cookie-checkBeanNotOfRequiredTypeException aufgrund von automatisch verknüpften Feldern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy