给对象属性赋值(DI, 依赖注入),几种方式:
- 构造函数赋值
- set 方法注入值
- 普通字段赋值
- 集合属性 (list/map/property)
- 案例(Dao/service/action实例,处理依赖关系)
- 常用的通过set方法注入
- 内部bean
- p名称空间
- 自动装配
- 注解
案例1:
beam.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--IOC容器, 给对象属性赋值 -->
<bean id="user" class="cn.itcast.c_di.User">
<property name="id" value="1000"></property>
<property name="name" value="Jacky"></property>
<!-- list集合赋值 -->
<property name="list">
<list>
<value>cn</value>
<value>usa</value>
</list>
</property>
<!-- map 集合赋值 -->
<property name="map">
<map>
<entry key="cn" value="China"></entry>
<entry key="usa" value="1234"></entry>
</map>
</property>
<!-- Properties对象赋值 -->
<property name="prop">
<props>
<prop key="cn">China</prop>
<prop key="usa">America</prop>
</props>
</property>
</bean>
</beans>
类
@Data
public class User {
private int id;
private String name;
// list集合
private List<String> list;
// Map集合
private Map<String,Object> map;
// Properties 对象
private Properties prop;
}
案例2:
beam.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用setter方法来注入属性依赖(使用最为普遍)
<bean id="userDao" class="com.xxjqr.spring01.di2.UserDao"></bean>
<bean id="userService" class="com.xxjqr.spring01.di2.UserService">
<property name="userDao" ref="userDao"></property> //name表示的也是属性名哦!
</bean>
<bean id="userAction" class="com.xxjqr.spring01.di2.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
-->
<!-- 内部bean
总结: 当创建的对象,不被容器其他地方引用的时候,可以这样写! 这样写不通用,内部对象只能用一次
这里,action如果是单例,内部bean默认就是单例; action如果是多例,内部bean就是多例
<bean id="userAction" class="com.xxjqr.spring01.di2.UserAction" scope="prototype">
<property name="userService">
<bean class="com.xxjqr.spring01.di2.UserService">
<property name="userDao">
<bean class="com.xxjqr.spring01.di2.UserDao"></bean>
</property>
</bean>
</property>
</bean>
-->
<!-- p名称空间给属性注入
<bean id="name" class="java.lang.String">
<constructor-arg value="丁丁"></constructor-arg>
</bean>
<bean id="user" class="com.xxjqr.spring01.di2.User" p:name-ref="name" p:sex="男" p:age="22">
</bean>
-->
<!-- 使用p名称空间来注入属性依赖(使用最为普遍)-->
<bean id="userDao" class="com.xxjqr.spring01.di2.UserDao"></bean>
<bean id="userService" class="com.xxjqr.spring01.di2.UserService" p:userDao-ref="userDao"></bean>
<bean id="userAction" class="com.xxjqr.spring01.di2.UserAction" p:userService-ref="userService"></bean>
<!-- 最后:
uesrDao和userService默认是单例的,因为他们内部没有维护一些需要变动的变量
userAction用来处理每次的请求不能设置为单例的
使用p名称空间的前提:
1.xmlns:p="http://www.springframework.org/schema/p"
2.spring3.0以后
-->
</beans>
类:
UserAction->UserService->UserDao
同样的结构,只是beam.xml的不同
自动装配
beam.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<!-- 自动装配(全局装配)
default-autowire="byName
-->
<!-- 自动装配(节点装配)
autowire=byName
(查看该类中的setter方法(如setUserDao),找到了UserDao,
然后在容器中找该名称对象,再通过setter方法完成注入)
autowire=byType
(查看该类中的setter方法(如setUserDao(UserDao xx))
,找到了UserDao类型,然后在容器中找该类型对象,再通过setter方法完成注入)
-->
<!-- 最后:
使用autowire的时候,名称和类型不能有重复的对象 -->
<bean id="userDao" class="com.xxjqr.spring01.auto_wire.UserDao"></bean>
<bean id="userService" class="com.xxjqr.spring01.auto_wire.UserService"></bean>
<bean id="userAction" class="com.xxjqr.spring01.auto_wire.UserAction"></bean>
</beans>
注解方式
导入schema文件 文件名为spring-context-2.5.xsd
beam.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 注解的方式,实现springIOC容器配置 -->
<!-- 1. 开启注解扫描 -->
<context:component-scan base-package="com.xxjqr.spring01.anno"></context:component-scan>
</beans>
类
@Controller //==@Controller("userAction")
@Data
public class UserAction {
@Resource //==@Resource("")
private UserService userService;
public void save(){
userService.save();
}
}
@Data
@Service
public class UserService {
@Resource
private UserDao userDao;
public void save(){
userDao.save();
}
}
@Repository
public class UserDao {
public void save(){
System.out.println("已经save");
}
}
public class App {
private ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml",App.class);
@Test
public void testUserAction() {
//创建容器
UserAction action = (UserAction) ac.getBean("userAction");
action.save();
}
}
注解总结:
@Component 表示一个组件(类),把当前组件加入ioc容器加入容器的组件的名称默认是类名第一个字母小写
@Component(“”) 指定加入ioc容器的组件类的类名
@Repository 标识是一个持久层的组件
@Service 标识是一个业务逻辑层的组件
@Controller 标识是一个控制层的组件
@Scope("prototype") 指定对象单例/多例
@Resource
- 默认根据修饰的字段名称会取ioc容器找对象自动注入
找到后注入 - 如果名称没有找到,再根据类型查找 找到后就立刻注入
如果改类型在ioc容器中有多个对象,报错! - 根据类型也没有找到对象,报错!
@Resource(name =””) 会根据指定的名称去容器找对象自动注入
配置方式与注解方式:
- 配置, 便于维护但配置过多,比较繁琐
- 注解, 开发方便但简化配置,不利于后期维护,如果修改对象创建、关系处理,需要改代码!