Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于自动连接字段,BeanNotOfRequiredTypeException_Java_Spring Mvc_Annotations_Tomcat7 - Fatal编程技术网

Java 由于自动连接字段,BeanNotOfRequiredTypeException

Java 由于自动连接字段,BeanNotOfRequiredTypeException,java,spring-mvc,annotations,tomcat7,Java,Spring Mvc,Annotations,Tomcat7,我还是Spring MVC的新手,在构建我的测试项目时,我从Tomcat日志中得到了以下信息: SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanCreationException: Error cre

我还是Spring MVC的新手,在构建我的测试项目时,我从Tomcat日志中得到了以下信息:

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)
我有两个用于用户和管理员的rolle服务,有三个接口:

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);
}
我如何修复它?

我在控制器中使用AdminServiceImpl:

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";
    } ....

在代码中的某个地方,您必须像这样自动连接
AdminServiceImpl

@Autowired
private AdminServiceImpl adminService;
两种方法都几乎不依赖于接口:

@Autowired
private AdminService adminService;
或启用CGLIB代理

类似问题

使用界面
AdminService
而不是工具


这个错误是由注释
@Transactional
Spring
运行时为
AdminService
创建一个代理引起的。当您的服务类实现一些接口时,Spring默认由JDK代理,这就是为什么会出现这个错误,因此,无论是在接口上使用@Autowired还是启用CGLIB代理,都可以解决这个问题

我解决了在spring应用程序上下文中使用代理目标类属性启用CGLIB代理的问题

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

我也面临同样的问题,但我通过以下解决方法解决了这个问题:

请用接口替换您的实现类。 例如:

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

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

在谷歌搜索我的问题时,我发现了很多类似的问题。然而,在我的例子中,我已经使用了一个接口。因此我认为这可能对其他人有所帮助:

如果您有两个同名的bean,也可能出现此异常


在我的例子中,applicationContext.xml中有额外的bean配置。问题出现在我合并两个应用程序之后。第二个定义了一个
@Resource
,其成员变量名与上面提到的第一个应用程序的bean名匹配。当然,第一个应用程序的bean配置不适合第二个应用程序通过
@Resource
包含的bean。

我在执行单元测试时也遇到了这个问题

我创建了一个模拟服务来实现真正的服务,以覆盖一些方法,以便测试一些用户案例

@Component
public static class FooServiceImplMock extends FooServiceImpl {
    @Override
    protected void bar() {
        // do some specific loginc here 
    }
}
但是当执行测试方法时

@Autowired
private Foo1ServiceImplMock foo1ServiceImplMock;
我犯了以下错误

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooServiceImplTest.FooServiceImplMock' is expected to be of type 'com.foo.business.impl.FooServiceImplTest$FooServiceImplMock' but was actually of type 'com.sun.proxy.$Proxy97'
原因:

在FooServiceImpl中使用了@Cacheable方法

@Cacheable("eventTypes")
从EnableCaching的javadoc我知道

org.springframework.cache.annotation.EnableCaching 
boolean proxyTargetClass()

Indicate whether subclass-based (CGLIB) proxies are to be created as opposed to standard Java interface-based proxies. The default is false.
因此,解析方式是显式地指定在spring应用程序contenxt中使用CGLIB

 <cache:annotation-driven proxy-target-class="true"/>

我在测试端点的一些
@SpringBootTest
类中也遇到了这个问题。端点依赖于在一些方法上具有
@Transactional
的DB服务

由于
@Transactional
,Spring截取并创建了一个代理类,因此Spock(或junit)很难注入正确的mock


我的解决方法是将DB服务向下推一层,并在中间层进行简单的Spock测试,而不受此影响。

当对现有类的测试开始失败时,我遇到了这个问题,测试的类型是“预期为……但实际上为'com.sun.proxy.$Proxy115'


结果是,我在添加到接口实现类的@Transactional方法上使用了Intellij的“pull method up[to interface]”,Intellij决定将@Transactional添加到接口方法声明中。如果一个接口中只有一个@Transactional方法,那么它似乎会把事情搞砸,导致此错误。

请确保已在上启用proxyTargetClass,如:

@EnableTransactionManagement(proxyTargetClass = true)

@谢尔盖:你可以自己修,这是个常见的问题。只要查找类型为
AdminServiceImpl
的自动连接字段,我很确定您有一些。也就是说,查找您实际使用的位置
AdminServiceImpl
。删除
Impl
以仅依赖接口。就这样!删除Impl以仅依赖于接口。如果我替你表演?我必须重新使用AdminService使用的所有AdminServiceImpl。@Serge:的确如此。事实上,如果仍然依赖类,为什么要将类和接口分开?
…Impl
出现的唯一位置是类定义中,而不是其他地方。请告诉我有关“autowire”的信息。如何正确地自动连接字段?我应该在接口中这样做,还是一切都做对了?使用接口而不是实现,并用@Qualifier注释以获得正确的类。救了我的命!非常感谢。伟大的你的建议正好解决了我的问题。不确定为什么有人投了反对票。或者如果您将
@EnableTransactionManagement
添加到配置中作为结果
@Transactional
开始工作。为了我
org.springframework.cache.annotation.EnableCaching 
boolean proxyTargetClass()

Indicate whether subclass-based (CGLIB) proxies are to be created as opposed to standard Java interface-based proxies. The default is false.
 <cache:annotation-driven proxy-target-class="true"/>
@EnableTransactionManagement(proxyTargetClass = true)