Spring的核心——控制反转
ioc: 反转控制. 创建对象的方式反转了.从我们自己创建对象,反转给spring(程序)来创建.
实现ioc思想需要,di做支持
di: 依赖注入.将必须的属性注入到对象当中.是实现ioc思想必须条件.
三种对象创建方式
- 无参构造创建对象
<!-- 创建方式一:spring调用无参构造创建对象 -->
<!-- scope:singleton:表示单例对象,在spring容器中只会存在一个实例 -->
<!-- scope:prototype:表示多例对象,每次获取都会创建一个新的对象;整合struts2时必须为多例 -->
<!-- 生命周期方法配置init,destroy -->
<bean name="user" class="com.bean.User" scope="singleton" init-method="init" destroy-method="destroy"></bean>
- 通过静态工厂的某个方法创建一个user对象
<bean name="user1" class="com.bean.UserFactory" factory-method="createUser"></bean>
- 实例工厂创建对象
<bean name="user2" factory-bean="userFactory" factory-method="createUser2"></bean>
<bean name="userFactory" class="com.bean.UserFactory"></bean>
静态工厂和实例工厂类如下:
public class UserFactory {
public static User createUser(){
System.out.println("通过静态工厂的某个方法创建一个user对象");
return new User();
}
public User createUser2(){
System.out.println("实例工厂创建对象");
return new User();
}
}
依赖注入的方式
- set方法(主要方式)
<!-- set方式注入 -->
8 <bean name="user" class="top.maniy.User">
9 <!-- 值类型注入 -->
10 <property name="name" value="maniy"/>
11 <property name="age" value="18"/>
12 <!-- 引用类型注入 -->
13 <property name="city" ref="city"/>
14 </bean>
- 构造方法注入
<bean name="user1" class="top.maniy.User">
<!-- 当构造方法参数位置不同,可以通过index确定参数位置 -->
<!-- 当构造方法参数类型不同,可以通过type确定参数类型 -->
<constructor-arg name="name" value="maniy" index="0" type="java.lang.String"/>
<constructor-arg name="city" ref="city"/>
</bean>
- p属性注入
<!-- p属性注入 -->
<!-- 需加入xmlns:p="http://www.springframework.org/schema/p" -->
<bean name="user2" class="com.bean.User" p:name="maniy" p:age="18" p:city-ref="city"/>
spel表达式注入
<!-- spel表达式注入;可以实现动态注入 -->
<bean name="user3" class=""top.maniy.User">
<property name="name" value="#{user.name}"/><!--取user的name赋给user3-->
<property name="age" value="#{user2.age}"/>
<property name="car" ref="car"/>
</bean>
复杂属性注入
public class CollectionBean {
private Object[] arr;//数组
private List list;//集合
private Map map;//map集合
private Properties properties;//资源文件
//get、set、toString方法省略
}
- Array
<!-- 数组注入 -->
<bean name="cb" class="top.maniy.CollectionBean">
<!-- 只有一个值时 -->
<!--<property name="arr" value="maniy"/>-->
<!-- 多值多元素注入 -->
<property name="arr">
<array>
<value>maniy</value>
<value>mark</value>
<ref bean="user3"/>
</array>
</property>
</bean>
- List\Set
<!-- 集合注入 -->
<bean name="cb2" class="top.maniy.CollectionBean">
<!-- 只有一个值时 -->
<!--<property name="list" value="maniy"/>-->
<!-- 多值多元素注入 -->
<property name="list">
<list>
<value>maniy</value>
<value>mark</value>
<ref bean="user3"/>
</list>
</property>
</bean>
- Map
<!-- map注入 -->
<bean name="cb3" class="top.maniy.CollectionBean">
<property name="map">
<map>
<entry key="name" value="maniy"/><!-- key:字符串,value:字符串 -->
<entry key="user" value-ref="user3"/><!-- key:字符串,value:对象 -->
<entry key-ref="user1" value-ref="user2"/><!-- key:对象,value:对象 -->
</map>
</property>
</bean>
- Properties
<!-- 资源注入 -->
<bean name="cb4" class=top.maniy.CollectionBean">
<property name="properties">
<props>
<prop key="driverClass">com.jdbc.mysql.Driver</prop>
<prop key="userName">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
注解方式
配置注解扫描
<!-- Spring 的注解开发:组件扫描(类上注解: 可以直接使用属性注入的注解) --> <context:component-scan base-package="com.itheima.spring.demo1"/>
@Component
Spring 中提供@Component 的三个衍生注解:(功能目前来讲是一致的)
- @Controller :WEB 层
- @Service :业务层
- @Repository :持久层
这三个注解是为了让标注类本身的用途清晰,Spring 在后续版本会对其增强
属性注入的注解:(使用注解注入的方式,可以不用提供 set 方法.)
-
@Value :用于注入普通类型.
-
@Autowired :自动装配:
默认按类型进行装配.
按名称注入:
@Qualifier:强制使用名称注入.
-
@Resource 相当于: @Autowired 和@Qualifier 一起使用.
-
@Scope:
singleton:单例
prototype:多例 -
Bean 的生命周期的配置
@PostConstruct :相当于 init-method
@PreDestroy :相当于 destroy-method
//@Component("user")
// @Service("user") // service层
// @Controller("user") // web层
@Repository("user")// dao层
//指定对象的作用范围
@Scope(scopeName="singleton")
public class User {
private String name;
@Value("18")
private Integer age;
//@Autowired //自动装配
//问题:如果匹配多个类型一致的对象.将无法选择具体注入哪一个对象.
//@Qualifier("city1")//使用@Qualifier注解告诉spring容器自动装配哪个名称的对象
@Resource(name="city2")//手动注入,指定注入哪个名称的对象
private City city;
@PostConstruct //在对象被创建后调用.init-method
public void init(){
System.out.println("我是初始化方法!");
}
@PreDestroy //在销毁之前调用.destory-method
public void destory(){
System.out.println("我是销毁方法!");
}
}
XML 和注解:
- XML :结构清晰.
- 注解 :开发方便.(属性注入.)
实际开发中还有一种 XML 和注解整合开发:
- Bean 有 XML 配置.但是使用的属性使用注解注入.