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();
}
}

通过构造函数动态注入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


构造器注入
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文件配置是,编译器无法及时检查的问题。