IoC的配置是通过Spring的xml文件的bean标签进行的。
一、 IOC配置
1、bean的实例化
bean有三种实例化方式:无参构造、静态工厂、实例工厂
1.1、无参构造
默认情况下会根据无参构造方法进行对象的实例化。
若没有无参构造方法则会创建失败。
1.1.1、bean标签属性
-
id:给对象在容器中提供一个唯一标识。用于获取对象。 class:指定类的全限定名。用于反射创建对象。默认情况下调用无参构造函数。
-
scope:指定对象的作用范围。
- singleton:默认值,单例的(在整个容器中只有一个对象).
- prototype:多例的
- request:将Spring 创建的 Bean 对象存入到 request 域中.
-session:将Spring 创建的 Bean 对象存入到 session 域中.
-global session:WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么globalSession 相当于 session。 -
init-method:指定类中的初始化方法名称。
-
destroy-method:指定类中销毁方法名称。比如DataSource的配置中一般需要指定destroy-method=“close”。
-
lazy-init:ApplicationContext实现的默认行为就是在启动时将所有 singletonbean进行实例化。lazy-init可以延迟初始化,设置lazy-init="true"使得Ioc容器在第一次需要bean的时候进行实例化。
package com.it1.bean;
public class UserInfo {
private String user_id;
private String user_name;
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
@Override
public String toString() {
return "UserInfo [user_id=" + user_id + ", user_name=" + user_name + "]";
}
public UserInfo(String user_id, String user_name) {
super();
this.user_id = user_id;
this.user_name = user_name;
}
public UserInfo() {
super();
}
}
XML:
<bean id="userInfo" class="com.it1.bean.UserInfo"></bean>
1.2、静态工厂
使用静态工厂创建实例,其中:
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
创建一个静态工厂类
package com.it1.factory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TeacherStaticFactory {
private static TeacherStaticFactory teacherStaticFactory =new TeacherStaticFactory();
public static TeacherStaticFactory createTeacher(){
System.out.println("静态工厂");
return teacherStaticFactory;
}
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"factory.xml"});
TeacherStaticFactory teacherStaticFactory =applicationContext.getBean("teacherFactory", TeacherStaticFactory.class);
}
}
XML:
<!-- 静态工厂-->
<bean id="teacherStaticFactory" class="com.it1.factory.TeacherStaticFactory" factory-method="createTeacher"></bean>
1.3、实例工厂
将工厂的创建交给Spring进行,使用工厂bean调用方法创建实例化对象。其中:
factory-bean 属性:用于指定实例工厂 bean 的 id。
factory-method 属性:用于指定实例工厂中创建对象的方法。
创建一个实例工厂
package com.it1.factory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TeacherFactory {
private static TeacherFactory teacherFactory =new TeacherFactory();
public TeacherFactory createTeacher(){
System.out.println("实例工厂");
return teacherFactory;
}
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"factory.xml"});
TeacherFactory teacherFactory =applicationContext.getBean("teacher", TeacherFactory.class);
}
}
XML:
<bean id="teacherFactory" class="com.it1.factory.TeacherFactory" ></bean>
<bean id="teacher" factory-method="createTeacher" factory-bean="teacherFactory"></bean>
注意:id和name的区别
Bean标签提供了两种标识Bean的Attribute:id和name
id用来标识bean,是唯一的,且只有一个,只允许以字母开头,其后只能为字母或数字或”-“。
name定义的是bean的alias,可以有多个,并可能与其他的bean重名,name允许特殊字符。
当多个重名的name同时存在时,先产生的bean会被后产生的bean覆盖
当id和name的值相同,通过值获取bean得到的是name对应的bean。
<bean id="person" class="com.luis.dto.Student"></bean>
<bean name="person" class="com.luis.dto.Teacher"></bean>
<!-- factory.getBean(“person”)返回的是Teacher对象-->
<!-- 若置bean的时候并没有声明ID属性,则采用全类限定名作为bean的id,此时称为匿名bean-->
<bean class="com.learnSpring.hellWorld"/>
<bean class="com.learnSpring.hellWorld"/>
<bean class="com.learnSpring.hellWorld"/>
<!-- 如果存在多个class属性都是一样的匿名的Bean,则根据Spring读取配置文件的顺序生成id-->
"com.learnSpring.hellWorld"
"com.learnSpring.hellWorld#0"
"com.learnSpring.hellWorld#1"
二、 DI配置
依赖注入(Dependency Injection)是 spring 框架核心 IoC 的具体实现。依赖指的是bean的属性,包括:简单类型(8种基本类型和String类型)的属性、POJO类型的属性、集合数组类型的属性。我们通过控制反转将实例化对象的交给IoC进行,但创建的对象没有依赖,因而需要Spring维护依赖关系,即依赖注入。
1、依赖注入的方式
写一个接口IAccountService
package com.it1.services;
public interface IAccountService {
}
1.1使用set方法注入
AccountServiceImpl实现接口 生成set方法
package com.it1.services;
import com.it1.controller.Test;
import com.it1.controller.UserInfoServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
public class AccountServiceImpl implements IAccountService{
//如果是经常变化的数据,并不适用于注入的方式
private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
}
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"Account.xml"});
//通过反射机制 通过配置文件的id 获取controller对象
AccountServiceImpl accountServiceImpl=applicationContext.getBean("accountServiceImpl",AccountServiceImpl.class);
accountServiceImpl.saveAccount();
}
}
XML:
<!-- 引用类型对象属性 单独写bean-->
<bean id="now" class="java.util.Date"></bean>
<bean id="accountServiceImpl" class="com.it1.services.AccountServiceImpl">
<property name="age" value="25"></property>
<property name="name">
<value>张三</value>
</property>
<!-- ref 依赖 birthday依赖于Date-->
<property name="birthday" ref="now"></property>
</bean>
1.2、构造方法注入
使用类中的构造函数,给成员变量赋值,通过在xml文件中的bean进行配置的方式给对象赋值。
构造方法注入涉及的标签:
- constructor-arg
- index:指定参数在构造函数参数列表的索引位置
- name:指定参数在构造函数中的名称
- value:它能赋的值是基本数据类型和 String 类型
- ref:它能赋的值是其他 bean 类型,且必须是在配置文件中配置过的 bean
AccountServiceImpl2实现接口 生成构造方法
package com.it1.services;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
public class AccountServiceImpl2 implements IAccountService {
//如果是经常变化的数据,并不适用于注入的方式
private String name;
private Integer age;
private Date birthday;
public AccountServiceImpl2(String name,Integer age,Date birthday){
this.name = name;
this.age = age;
this.birthday = birthday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
}
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"Account.xml"});
AccountServiceImpl2 accountServiceImpl2= applicationContext.getBean("accountServiceImpl2",AccountServiceImpl2.class);
accountServiceImpl2.saveAccount();
}
}
XML:
<!-- 引用类型对象属性 单独写bean-->
<bean id="now" class="java.util.Date"></bean>
<!-- 按照name-->
<bean id="accountServiceImpl2" class="com.it1.services.AccountServiceImpl2">
<constructor-arg name="age" value="23"></constructor-arg>
<constructor-arg name="name" value="23"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!-- 按照索引-->
<bean id="accountServiceImpl2" class="com.it1.services.AccountServiceImpl2">
<constructor-arg index="0" value="23"></constructor-arg>
<constructor-arg index="1" value="23"></constructor-arg>
<constructor-arg index="2" ref="now"></constructor-arg>
</bean>
<!-- 按照类型-->
<bean id="accountServiceImpl2" class="com.it1.services.AccountServiceImpl2">
<constructor-arg type="java.lang.String" value="23"></constructor-arg>
<constructor-arg type="java.lang.Integer" value="23"></constructor-arg>
<constructor-arg type="java.util.Date" ref="now"></constructor-arg>
</bean>
1.3、p空间名称注入
p名称注入是set方法的一种简写方式,首先需引入p命名空间:
xmlns:p="http://www.springframework.org/schema/p"
<bean id="accountServiceImpl" class="com.it1.services.AccountServiceImpl"p:age="25" p:name="李四" p:birthday-ref="now"></bean>
1.4、引用类型
AccountServiceImpl3实现接口 生成构造方法
package com.it1.services;
import com.it1.bean.UserInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.*;
public class AccountServiceImpl3 implements IAccountService {
private String[] myStrs;
private List<UserInfo> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List<UserInfo> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyProps(Properties myProps) {
this.myProps = myProps;
}
public void saveAccount(){
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(mySet);
System.out.println(myMap);
System.out.println(myProps);
}
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"Account.xml"});
AccountServiceImpl3 accountServiceImpl3 =applicationContext.getBean("accountServiceImpl3", AccountServiceImpl3.class);
accountServiceImpl3.saveAccount();
}
}
XML:
<!-- 复杂集合-->
<bean id="accountServiceImpl3" name="accountServiceImpl3" class="com.it1.services.AccountServiceImpl3">
<property name="myList">
<list>
<value>1List</value>
<value>2List</value>
<value>3List</value>
<value>4List</value>
<value>4List</value>
<!-- 如果是引用数据类型使用<bean></bean>-->
<!-- <bean id="userInfo" class="com.it1.bean.UserInfo">-->
<!-- <property name="user_id" value="12"></property>-->
<!-- </bean>-->
<!-- <bean id="userInfo" class="com.it1.bean.UserInfo"></bean>-->
<!-- <bean id="userInfo" class="com.it1.bean.UserInfo"></bean>-->
</list>
</property>
<property name="mySet">
<set>
<value>1Set</value>
<value>2Set</value>
<value>3Set</value>
<value>4Set</value>
<value>4Set</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="map1" value="map1"></entry>
<entry key="map2" value="map2"></entry>
<entry key="map2" value="map2"></entry>
<entry key="map3"><value>map3</value></entry>
</map>
</property>
<property name="myStrs">
<array>
<value>1array</value>
<value>2array</value>
<value>3array</value>
<value>4array</value>
<value>4array</value>
</array>
</property>
<property name="myProps">
<props>
<prop key="prop">prop1</prop>
<prop key="prop">prop2</prop>
<prop key="prop">prop2</prop>
<prop key="prop">prop3</prop>
</props>
</property>
</bean>