Spring基于XML的IOC配置

1. 什么是Spring

无论是否使用过,Spring的大名相信任何Java程序员都不陌生吧,那么究竟什么是Spring呢?它有什么用?使用Spring开发有什么优势?这些问题老王就不在这啰嗦了,下面将直接通过案例说明。为了方便初学者再去百度上述问题,老王还是粘贴一下官方介绍吧。

Spring是分层的Java SE/EE应用轻量级开源框架,以IOC(Inverse Of Control)控制反转和AOP(Aspect Oriented Programming)面向切面编程为内核,提供了展现层Spring MVC和持久层Spring JDBC,以及业务层事务管理等众多的企业级应用技术,还能整合开源界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

2. 什么是IOC

IOC(Inverse Of Control)控制反转,所谓控制反转就是把创建对象和维护对象的关系的权利从程序中转移到Spring的容器中,而程序本身不再维护。之前开发中,需要实例对象时直接new一个对象即可,学习Spring之后,从Spring工厂(容器)中即可获得,通过该方式可以大大减少程序之间的耦合。

3. IOC案例演示

3.1 需要实例对象时直接new一个对象

public interface IAccountDao {
	void saveAccount();
}

public class AccountDaoImpl implements IAccountDao {
	@Override
	public void saveAccount() {
		System.out.println("保存了账户");
	}
}

public interface IAccountService {
	void saveAccount();
}

public class AccountServiceImpl implements IAccountService {
	private IAccountDao accountDao = new AccountDaoImpl(); //此处的依赖关系有待解决
	
	@Override
	public void saveAccount() {
		accountDao.saveAccount();
	}	
}

3.2 通过IOC让Spring管理资源

创建Spring配置文件,文件名任意(一般命名为applicationContext.xml),位置任意(一般在classpath下),具体如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans.xsd">
 
<!-- bean标签:用于配置让 Spring创建对象,并且存入 ioc容器中
	* id:对象的唯一标识
	* class:指定要创建对象的全限定类名
-->
<bean id="accountService" class="com.joker.service.impl.AccountServiceImpl">
</bean>
<bean id="accountDao" class="com.joker.dao.impl.AccountDaoImpl"></bean>
</beans>

测试配置是否成功:

public class SpringTest {
	public static void main(String[] args) {
	
		//使用 ApplicationContext接口获取 Spring容器
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//根据 bean的 id获取对象
		IAccountService aService = (IAccountService) ac.getBean("accountService");
		IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
		System.out.println(aService);
		System.out.println(aDao);	
	}
}

4. 配置文件详解

4.1 bean标签的作用与属性

作用:用于配置对象让Spring来创建的,默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。

属性:

  • id:给对象在容器中提供一个唯一标识,用于获取对象。

  • class:指定类的全限定类名,用于反射创建对象,默认情况下调用无参构造函数。

    扫描二维码关注公众号,回复: 8774518 查看本文章
  • scope:指定对象的作用范围:

    • singleton:默认值,单例的。
    • prototype:多例的。
    • request:WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中。
    • session:WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中。
    • global session:WEB项目中,应用在Portlet环境,如果没有Portlet环境,那么globalSession相当于session。
  • init-method:指定类中的初始化方法名称。

  • destroy-method:指定类中销毁方法名称。

4.2 bean的作用范围和生命周期

  • 单例对象:scope=“singleton”,一个应用只有一个对象的实例,它的作用范围就是整个引用。
    对象出生:当应用加载,创建容器时,对象就被创建了。
    对象活着:只要容器在,对象一直活着。
    对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
  • 多例对象:scope=“prototype”,每次访问对象时,都会重新创建对象实例。
    对象出生:当使用对象时,创建新的对象实例。
    对象活着:只要对象在使用中,就一直活着。
    对象死亡:当对象长时间不用时,被java的垃圾回收器回收了。

4.3 实例化bean的三种方式

  1. 使用默认无参构造函数

    <!-- 在默认情况下,它会根据默认无参构造函数来创建类对象,如果 bean中没有默认无参构造函数,将会创建失败 -->
    <bean id="accountService" class="com.joker.service.impl.AccountServiceImpl"/>
    
  2. 使用静态工厂的方法创建对象

    //模拟一个静态工厂,创建业务层实现类
    public class StaticFactory {
    	public static IAccountService createAccountService(){
    		return new AccountServiceImpl();
    	}
    }
    
    <!-- 此种方式是使用 StaticFactory类中的静态方法 createAccountService创建对象,并存入 Spring容器
    	* id:指定 bean的 id
    	* class:指定静态工厂的全限定类名
    	* factory-method:指定生产对象的静态方法
    -->
    <bean id="accountService" class="com.joker.factory.StaticFactory" factory-method="createAccountService"></bean>
    
  3. 使用实例工厂的方法创建对象

    //模拟一个实例工厂,创建业务层实现类,此工厂创建对象,必须现有工厂实例对象,再调用方法
    public class InstanceFactory {
    	public IAccountService createAccountService(){
    		return new AccountServiceImpl();
    	}
    }
    
    <!-- 此种方式是先把工厂的创建交给 Spring来管理,然后在使用工厂的 bean来调用里面的方法
    	* factory-bean:用于指定实例工厂 bean的 id
    	* factory-method:用于指定实例工厂中创建对象的方法
    -->
    <bean id="instancFactory" class="com.joker.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instancFactory" factory-method="createAccountService"></bean>
    

5. 依赖注入

依赖注入(Dependency Injection),它是Spring框架核心IOC的具体实现。我们的程序在编写时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但不会消除。例如我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

5.1 构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让Spring框架来为我们注入,具体代码如下:

public class AccountServiceImpl implements IAccountService {
	private String name;
	private Integer age;
	private Date birthday;
	
	public AccountServiceImpl(String name, Integer age, Date birthday) {
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}
	
	@Override
	public void saveAccount() {
		System.out.println(name+","+age+","+birthday);
	}
}
<!-- 使用构造函数的方式给 service中的属性传值,要求类中需要提供一个对应参数列表的构造函数
	constructor-arg标签:
		* index:指定参数在构造函数参数列表的索引位置
		* type:指定参数在构造函数中的数据类型
		* name:指定参数在构造函数中的名称,用这个找给谁赋值
		* value:它能赋的值是基本数据类型和 String类型
		* ref:它能赋的值是其他 bean类型,也就是说,必须得是在配置文件中配置过的 bean
-->
<bean id="accountService" class="com.joker.service.impl.AccountServiceImpl">
	<constructor-arg name="name" value="张三"></constructor-arg>
	<constructor-arg name="age" value="18"></constructor-arg>
	<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>

5.2 set方法注入

顾名思义,就是在类中提供需要注入成员的set方法,具体代码如下:

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;
	}
	
	@Override
	public void saveAccount() {
	System.out.println(name+","+age+","+birthday);
	}
}
<!-- 使用 set方法的方式给 service中的属性传值,要求类中需要提供相应属性的 set方法
	property标签:
		* name:找的是类中 set方法后面的部分
		* ref:给属性赋值是其他 bean类型的
		* value:给属性赋值是基本数据类型和 string类型的
-->
<bean id="accountService" class="com.joker.service.impl.AccountServiceImpl">
	<property name="name" value="李四"></property>
	<property name="age" value="21"></property>
	<property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

5.3 使用p名称空间注入数据(本质还是调用set方法)

此种方式是通过在xml中导入p名称空间,使用p:propertyName来注入数据,它的本质仍然是调用类中的set方法实现注入功能。

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;
	}
	
	@Override
	public void saveAccount() {
	System.out.println(name+","+age+","+birthday);
	}
}
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="accountService" class="com.joker.service.impl.AccountServiceImpl"
		p:name="王五" p:age="21" p:birthday-ref="now"/>
	<bean id="now" class="java.util.Date"></bean>
</beans>

5.4 注入集合属性

顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。我们这里介绍注入数组、List、Set、Map、Properties,具体代码如下:

public class AccountServiceImpl implements IAccountService {
	private String[] myStrs;
	private List<String> 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<String> 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;
	}
	
	@Override
	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);
	}
}
<!-- 注入集合数据
	List结构:array、list、set
	Map结构的:map、entry、props、prop
	在注入集合数据时,只要结构相同,标签可以互换
-->
<bean id="accountService" class="com.joker.service.impl.AccountServiceImpl">
	<!-- 给数组注入数据 -->
	<property name="myStrs">
		<set>
			<value>AAA</value>
			<value>BBB</value>
			<value>CCC</value>
		</set>
	</property>
	
	<!-- 注入 list集合数据 -->
	<property name="myList">
		<array>
			<value>AAA</value>
			<value>BBB</value>
			<value>CCC</value>
		</array>
	</property>
	
	<!-- 注入 set集合数据 -->
	<property name="mySet">
		<list>
			<value>AAA</value>
			<value>BBB</value>
			<value>CCC</value>
		</list>
	</property>
	
	<!-- 注入 Map数据 -->
	<property name="myMap">
		<props>
			<prop key="testA">aaa</prop>
			<prop key="testB">bbb</prop>
		</props>
	</property>
	
	<!-- 注入 properties数据 -->
	<property name="myProps">
		<map>
			<entry key="testA" value="aaa"></entry>
			<entry key="testB">
				<value>bbb</value>
			</entry>
		</map>
	</property>
</bean>
发布了25 篇原创文章 · 获赞 0 · 访问量 465

猜你喜欢

转载自blog.csdn.net/weixin_45990046/article/details/103749419