简体   繁体   中英

Spring constructor dependency injection - with vs. without autowired

I had encountered a problem described in this question , which I've already resolved by adding @Autowired annotation to constructor. Now I wonder, why it helped. What is a difference between

public RegistrationController(UserDao userDao) {
    this.userDao = userDao;
}

and

@Autowired
public RegistrationController(UserDao userDao) {
    this.userDao = userDao;
}

In both cases, userDao is injected to Controller. Only difference I discovered is that entityManager tagged with @persistenceContext annotation is injected into userDao only in the second example. But I don't know why. Any clues? And is there any other differences?

EDIT: my servlet context looks like this:

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

    <!-- 
    Adds some default beans (HandlerAdapter, HandlerMapping, Binding Initializer...). It also turn on some annotations. 
    Explanation in https://stackoverflow.com/questions/28851306/spring-framework-what-is-the-purpose-of-mvcannotation-driven

    WITHOUT THIS, @RequestMapping ANNOTATIONS ARE LOADED, BUT MAPPING DO NOT WORK!!
    -->
    <mvc:annotation-driven />

<!--    Set loading annotations from classes
    <context:component-scan base-package="com.fido.pia"/>-->

    <!--manual homepage-->
    <mvc:view-controller path="/" view-name="home"/>

    <!--view resolver-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!--static resources - request will be handeled by ResourceHttpRequestHandler-->
    <mvc:resources mapping="/resources/**" location="/resources/" />

    <!--database config-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/pia" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <!--entity manager factory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="packagesToScan" value="com.fido.pia.*/**" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!--<property name="generateDdl" value="true" />-->
                <property name="showSql" value="true" />
            </bean>
        </property>
    </bean>

    <!-- Transactions -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!--Set loading annotations from classes-->
    <context:component-scan base-package="com.fido.pia"/>
</beans>

Edit 2: Controller:

package com.fido.pia;

import com.fido.pia.dao.UserDao;
import com.fido.pia.model.User;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/register")
public class RegistrationController {

    private UserDao userDao;

    @Autowired
    public RegistrationController(UserDao userDao) {
        this.userDao = userDao;
    }

    @RequestMapping(method = RequestMethod.POST)
    @Transactional
    public void registrationSubmit(HttpServletRequest request, HttpServletResponse response) 
            throws IOException{
        String username = request.getParameter("first_name");

        userDao.save(new User("test"));

        response.sendRedirect("/");
    }
}

Dao:

package com.fido.pia.dao;

import com.fido.pia.model.User;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;


@Repository
public class UserDao {

    @PersistenceContext
    protected EntityManager entityManager;

    public User save(User row) {
        if(row.isNew()) {
            entityManager.persist(row);
            return row;
        } else {
            return entityManager.merge(row);
        }
    }   
}

Exist two forms for injection most use of the objects!

- First 
  @Autowired, 
 - Second in constructor 
 @Autowired
 constructor(Object object)
 - other
 @Autowired
 setObjectMehod(Object object)

When an interface is implemented for more than two objects, it is necessary to qualify the object to be inserted.

Always every object that is to be injected into a component , the most common @Repository, @Services, @Controller and @Component each with its proper scope.

Injections have the same purpose are only different ways and needs as needed by the object

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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