Spring Bean注入属性有哪几种方式呢?(Spring面试必问)

1,setter注入;

2,构造器注入

3,注解注入

4,java Config注入

使用setter方法运行时注入:(使用频率最高)

public class UserServiceImpl implements UserService {
    private UserDAO userDAO;
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
        System.out.println(this.hashCode() + ":正在调用Setter方法注入,setUserDAO(" + userDAO + ")");
    }
      
    @Override
    public void createUser() {
        System.out.println(this.hashCode() + ":正在调用UserService.createUser()");
        userDAO.insert();
    }
}    

dao service 分层初始化详情 · MingCaiXiong/spring-bean-learn@072729f

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="top.xiongmingcai.spring.injection.dao.UserDAOImpl" id="userDAO"/>

    <bean class="top.xiongmingcai.spring.injection.service.UserServiceImpl" id="userService">
        <!--setter方法运行时注入-->
        <property name="userDAO" ref="userDAO"/>
    </bean>
</beans>

使用 UserService 服务

public class InjectionApplication {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:injection.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        userService.createUser();
    }
}

使用UserService详情

通过构造函数动态注入userDao对象

 //通过构造函数注入
    public UserServiceImpl(UserDAO userDAO) {
        this.userDAO = userDAO;
        System.out.println(this.hashCode() + ":正在调用构造函数注入,UserServiceImpl(" + userDAO + ")");
    }

对于构造函数注入来说实际开发中并不推荐使用,因为使用构造函数注入UserDao 和UserService 出现紧密耦合,

假如在程序执行前并没有准备好UserDao,意味着UserService是无法创建的,因为这是UserService创建的强制要求

<bean class="top.xiongmingcai.spring.injection.dao.UserDAOImpl" id="userDAO"/>

<bean class="top.xiongmingcai.spring.injection.service.UserServiceImpl" id="userService">
    <!--setter方法运行时注入-->
    <!--<property name="userDAO" ref="userDAO"/>-->
    <!--构造函数动态注入userDao对-->
    <constructor-arg name="userDAO" ref="userDAO"/>
</bean>

使用注解进行注入

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <context:component-scan base-package="top.xiongmingcai.spring"/>
</beans>

在xml文件配置了context:component-scan标签后,spring容器可以自动去扫描base-pack所指定的包或其子包下面的java类文件,如果扫描到有@Component、@Controller、@Service 、@Repository等注解修饰的Java类,则将这些类注册为spring容器中的bean。

变量(filed)注入

@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource
    private UserDAO userDAO;

or

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDAO userDAO;

变量注入是在IOC容器初始化中就完成注入工作并不需要 get/set

autowird

构造器注入

private UserDAO userDAO;

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

注意:@Resource 注解并不能通过构造器注入

set方法注入

@Resource
public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
    System.out.println(this.hashCode() + ":正在调用Setter方法注入,setUserDAO(" + userDAO + ")");
}

or

@Autowired
public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
    System.out.println(this.hashCode() + ":正在调用Setter方法注入,setUserDAO(" + userDAO + ")");
}

java Config注入

@Configuration
public class AppConfig {
    @Bean//默认方法名为BeanID
    public UserDAO userDAO() {
        return new UserDAOImpl();
    }

    @Bean("userService")
    public UserService initService() {
        UserService userService = new UserServiceImpl();
        userService.setUserDAO(userDAO());
        return userService;
    }
}

相对于注解注入的优势:

1,不破坏原始代码,(不在原始代码中添加任何东西)

2,解决了 xml文件配置是,编译器无法及时检查的问题。

使用 java Config 注入 · MingCaiXiong/spring-bean-learn@02e1858