简体   繁体   English

如何在Spring MVC中实现DI?

[英]How to implement DI in Spring MVC.?

I have a confusion in Dependency Injection in Spring MVC. 我对Spring MVC中的依赖注入感到困惑。

First Code:- 第一个代码:-

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private Userdao udo;



    @Override
    @Transactional
    public List<Positions> plist() {
        return udo.plist();
    }
}

It is working Fine. 运行正常。 I would like to implement Dependency Injection in this class.Am doing right or wrong? 我想在此类中实现依赖注入。是对还是错?

second code:- 第二个代码:

`@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private Userdao udo;

    public UserServiceImpl(Userdao udo) {
        this.udo = udo;
    }

    @Override
    @Transactional
    public List<Positions> plist() {
        return udo.plist();
    }
}

Its not working. 它不起作用。 ERROR: org.springframework.web.context.ContextLoader - Context initialization failed 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: com.xxx.Services.UserService com.xxx.java.HomeController.uservice; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl' defined in file [D:\\xxxWorkspace\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\abcd\\WEB-INF\\classes\\com\\xxx\\ServiceImp\\UserServiceImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.xxx.ServiceImp.UserServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.xxx.ServiceImp.UserServiceImpl.<init>()

I am a beginner .please help me to solve this.How to implement DI in Spring MVC. 我是一个初学者。请帮助我解决这个问题。如何在Spring MVC中实现DI。

You can do this two ways. 您可以通过两种方式执行此操作。

  1. You can use field based autowiring. 您可以使用基于字段的自动装配。 But in this case you will need a default constructor. 但是在这种情况下,您将需要默认的构造函数。

     @Service @Transactional public class UserServiceImpl implements UserService { @Autowired // field based DI private Userdao udo; // default constructor public UserServiceImpl() {} @Override @Transactional public List<Positions> plist() { return udo.plist(); } } 
  2. You can use constructor based dependency injection. 您可以使用基于构造函数的依赖注入。 To do this simply move your @Autowire annotation to your constructor. 为此,只需将@Autowire注释移至构造函数即可。 And remove it from the field. 并将其从现场移除。

     @Service @Transactional public class UserServiceImpl implements UserService { private Userdao udo; @Autowired // constructor based DI public UserServiceImpl(Userdao udo) { this.udo = udo; } @Override @Transactional public List<Positions> plist() { return udo.plist(); } } 

First setup is alright, and should work. 第一次安装就可以了,应该可以。

In the second setup you're getting following exception 在第二种设置中,您将获得以下异常

class [com.xxx.ServiceImp.UserServiceImpl]: No default constructor found;

Which means what it says, since you've defined a constructor public UserServiceImpl(Userdao udo) Spring can't find an no-argument constructor. 这意味着它的含义,因为您已经定义了构造函数public UserServiceImpl(Userdao udo) Spring找不到无参数的构造函数。

You can either remove this constructor and use the first one or you can define the no argument constructor yourself. 您可以删除此构造函数并使用第一个构造函数,也可以自己定义no参数构造函数。

You shouldn't actually need to define a constructor in a bean as you're not going to create bean object yourself. 实际上,您不需要在bean中定义构造函数,因为您不会自己创建bean对象。 You would only need it if you're autorwiring constructor arguments. 仅当您要autor连线构造函数参数时,才需要它。

If you're trying to autowire constructor then you can do it like below. 如果您尝试自动构造器,则可以如下所示。

@Service
@Transactional
public class UserServiceImpl implements UserService {

    private Userdao udo;

    @Autowired //autowired constructor, instead of the field
    public UserServiceImpl(Userdao udo) {
        this.udo = udo;
    }

    @Override
    @Transactional
    public List<Positions> plist() {
        return udo.plist();
    }
}

In simple words: If you define a constructor (overloaded) then you must use the @Autowired annotation on the constructor, if you do not define a constructor, then you must use the @Autowired annotation for each Object you need to add as dependency injection. 简而言之:如果定义了一个构造函数(重载),则必须在构造函数上使用@Autowired批注;如果未定义构造函数,则必须对需要作为依赖项注入添加的每个Object使用@Autowired批注。 For example: 例如:

With constructor overloaded: 使用构造函数重载:

@Service
@Transactional
public class UserServiceImpl implements UserService {

    private final Userdao userDao;
    private final RoleDao roleDao;

    @Autowired
    public UserServiceImpl(Userdao userDao, RoleDao roleDao) {
        this.userDao = userDao;
        this.roleDao = roleDao;
    }

}

Without constructor overloaded 没有构造函数重载

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    // default constructor
    public UserServiceImpl() {}

}

Defining a constructor with a single @Autowired is better than having many objects @Autowired 用一个@Autowired定义一个构造函数比拥有多个@Autowired对象更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM