Spring IOC 依赖注入( 二 )

目录

1、什么是IOC

2、什么是DI

3、第一个IOC示例程序 -- 通过id获取对象(重点)

1、创建一个Java工程:

                  2、导入jar包:

4、IOC示例程序 -- 通过类型获取对象(重点)

5、IOC示例程序 -- 通过构造方法参数名注入值

打印结果:​

6、IOC示例程序 -- index属性指定参数的位置

7、IOC示例程序 -- 根据参数类型注入

8、IOC之 P名称空间

9、测试null值的使用

10、IOC之子对象的赋值测试(重点)

实验8:引用其他bean★

11、IOC之内部Bean的使用

实验9:引用内部bean

12、IOC之List属性的赋值

实验10:使用list子元素为List类型的属性赋值

13、IOC之Map属性的赋值

实验11:使用map子元素为Map类型的属性赋值

14、IOC之Properties属性的赋值

实验12:使用prop子元素为Properties类型的属性赋值​

15、IOC之util 名称空间

16、IOC之级联属性赋值

实验14:给bean的级联属性赋值

17、IOC之静态工厂方法创建Bean

实验15:配置通过静态工厂方法创建的bean

图解:

18、IOC之工厂实例方法创建Bean

实验16:配置通过实例工厂方法创建的bean

流程图解:

19、IOC之FactoryBean接口方式创建对象

实验17:配置FactoryBean接口创建Bean对象

图解流程:

20、IOC之继承Bean配置

实验18:通过继承实现bean配置信息的重用

图解:先比较parent与id是否相同,再拿class进行比较,


1、什么是IOC

IOC 全称指的是 Inverse Of Control 控制反转。

原来我们使用Spring之前对象都是通过代码 new 对象()来自己进行创建。

现在使用了Spring之后。只需要在Spring的配置文件中进行配置,那么spring就会帮我们new出对象来。

2、什么是DI

DI 指的是Dependency Injection 。是依赖注入的意思。

BookService{
    BookDao bookDao;

    public void setBookDao( BookDao bookDao ){
        this.bookDao = bookDao;
    }
}

只需要配置就可以把依赖的对象的值注入到引用中。

3、第一个IOC示例程序 -- 通过id获取对象(重点)

实验1:通过IOC容器创建对象,并为属性赋值★

1、创建一个Java工程:

创建相应的类

person类代码

为节省空间,省略get\set方法,toString不写

package com.webcode.pojo;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/** * @author Administrator *
 */
public class Person {	

	private Integer id;
	private String name;
	private Integer age;
	private String phone;
	private Car car;
	
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Person(Integer id, String name, Integer age, String phone, Car car) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.phone = phone;
		this.car = car;
	}
	

Car 类的代码

public class Car {
	
/*
    省略 get\set方法 和 toString方法不写
*/
	private String name;
	private String carNo;
	public Car() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Car(String name, String carNo) {
		super();
		this.name = name;
		this.carNo = carNo;
	}
}

2、导入jar包:

  • commons-logging-1.1.3.jar
  • log4j-1.2.17.jar
  • spring-beans-4.3.18.RELEASE.jar
  • spring-context-4.3.18.RELEASE.jar
  • spring-core-4.3.18.RELEASE.jar
  • spring-expression-4.3.18.RELEASE.jar

applicationContext.xml配置文件内容如下:

<!-- 
	bean标签标识要配置一个bean对象
	class 属性配置你要陪哪个Bean对象的全类名
	id 属性给配置的Bean对象起一个唯一标识
 -->
	<bean id="p1" class="com.webcode.pojo.Person">
		<!-- 
			property 标签配置属性的值
				name 标识你要配置哪个属性
				value 属性配置这个属性的值
	 	-->
	 	<property name="id" value="1"></property>
	 	<property name="name" value="旻"></property>
		<property name="age" value="25"></property>
 		<property name="phone" value="148999999"></property>
	</bean>

测试的代码:

        @Test
	public void test1()throws Exception {
		//ApplicationContext 表示SpringIOC 容器
		ApplicationContext applicationContext  =  new ClassPathXmlApplicationContext("applicationContext.xml");
		//使用了Spring之后。对象都交给Spring窗口来创建和管理
		//Spring 容器就是一个map,然后id是key class 时哪个value
		Person person = (Person) applicationContext.getBean("p1");
		System.out.println(person);
	}

打印结果:

问题:

1、FileSystemXmlApplicationContext怎么用?

答:跟使用JavaSE的相对路径一样

2、Bean是在什么时候被创建的?

答:在创建Spring容器的时候,创建Bean对象(默认)

  1. 如果调用getBean多次,会创建几个?

答:默认创建同一个

 

常见的错误:

指定的id不存在。找不到bean对象。

4、IOC示例程序 -- 通过类型获取对象(重点)

实验2:根据bean的类型从IOC容器中获取bean的实例★

配置文件代码:

	<bean id="p2" class="com.webcode.pojo.Person" >
		<!-- 	property 标签配置属性的值
				name 标识你要配置哪个属性
				value 属性配置这个属性的值 -->
	 	
	 	<property name="id" value="2"></property>
	 	<property name="name" value="旻"></property>
		<property name="age" value="25"></property>
 		<property name="phone" value="148999999"></property>
	</bean>
      @Test
      public void test2()throws Exception{
		ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
		
		 * 
		 * 按类型查找,找到一个就直接返回
		 * 没有找到就报错
		 * 找到多个也报错
		 * 
		System.out.println(applicationContext.getBean(Person.class));
	}

常见错误说明:

按类型查找,找不到就报错

当在applicationContext.xml配置文件中。有多个同Person.class类型实现的时候。

5、IOC示例程序 -- 通过构造方法参数名注入值

实验3:通过构造器为bean的属性赋值

        <bean id="p3" class="com.webcode.pojo.Person">
		
		<!-- 	constructor-arg 是按构造器参数赋值
				name	给哪个属性赋值
				value	传递的参数值 -->
		
		<constructor-arg name="name" value="王玄策" />
		<constructor-arg name="id" value="3" />
		<constructor-arg name="age" value="38" />
		<constructor-arg name="phone" value="198745632" />
	</bean>  

测试代码:

        @Test
	public void test3()throws Exception{
		 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		 System.out.println(applicationContext.getBean("p3"));
	}

打印结果:

6、IOC示例程序 -- index属性指定参数的位置

实验4:通过index属性指定参数的位置

        <bean id="p4" class="com.webcode.pojo.Person">
		
			<!-- constructor-arg 是按构造器参数赋值
				name	给哪个属性赋值
				value	传递的参数值 -->
		
		<constructor-arg index="1" value="大汉光武" />
		<constructor-arg index="0" value="4" />
		<constructor-arg index="2" value="26" />
		<constructor-arg index="3" value="1888951233" />
	</bean> 

测试代码:

        @Test
	public void test4()throws Exception{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println(applicationContext.getBean("p4"));
	}

打印结果:

7、IOC示例程序 -- 根据参数类型注入

实验5:根据参数类型注入


	public Person(Integer id, String name, Integer age, String phone) {
		super();
		System.out.println("创建了Person==有参");
		this.id = id;
		this.name = name;
		this.age = age;
		this.phone = phone;
	}
	
	public Person(Integer id, String name, String phone,Integer age) {
		super();
		System.out.println("创建了Person==有参");
		this.id = id;
		this.name = name;
		this.age = age;
		this.phone = phone;
	}

配置信息:

        <bean id="p5" class="com.webcode.pojo.Person">
		<!-- Integer id, String name, Integer age, String phone
		
			constructor-arg 是按构造器参数赋值
				index	构造参数的索引
				value	传递的参数值 -->
		
		 <constructor-arg index="0" value="4" type="java.lang.Integer"></constructor-arg>
		 <constructor-arg index="1" value="帅才" type="java.lang.String"></constructor-arg>
		 <constructor-arg index="2" value="19" type="java.lang.Integer"></constructor-arg>
		 <constructor-arg index="3" value="18" type="java.lang.String"></constructor-arg>
		
	</bean> 

测试代码:

        @Test
	public void test5()throws Exception{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println(applicationContext.getBean("p5"));
	}

打印结果:

8、IOC之 P名称空间

实验6:通过p名称空间为bean赋值

配置信息:

		<!-- p名称空间是同过set方法复制 -->
	
	<bean id="p6" class="com.webcode.pojo.Person"
		p:id="6"  p:age="25" p:name="旻"  p:phone="145665389">
				
	</bean>

测试代码:

        @Test
	public void test6()throws Exception{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println(applicationContext.getBean("p6"));
	}

打印结果:

9、测试null值的使用

实验7:测试使用null值

配置信息:

        <!-- 测试null值的应用 -->
	<bean id="p7 " class="com.webcode.pojo.Person">
		<property name="id" value="7"></property>
		<property name="name"><null></null></property>
	</bean>

测试代码:

	@Test
	public void test7() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) applicationContext.getBean("p7");
		System.out.println( person.getName().length() );
	}

10、IOC之子对象的赋值测试(重点)

实验8:引用其他bean★

创建个新的工程。测试Spring的开发环境。此不重复。请参阅前面,环境搭建。

Car对象

public class Car {

	private String name;
	private String carNo;

public class Person {

	private Integer id;
	private String name;
	private Integer age;
	private String phone;
	private Car car;

配置信息:

        <bean id="car" class="com.webcode.pojo.Car" p:name="宝马" p:carNo="京B123412"/>

	<bean id="p8" class="com.webcode.pojo.Person">
		<property name="id" value="8" />
		<!-- 
			car属性,可以通过ref(引用的意思)某个指定id值的对象
		 -->
		<property name="car" ref="car" />
	</bean>

测试代码:

	@Test
	public void test8() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) applicationContext.getBean("p8");
		System.out.println( person );
	}

打印结果:

11、IOC之内部Bean的使用

实验9:引用内部bean

配置信息:

        <!--  引用内部bean -->
	<bean id="p9" class="com.webcode.pojo.Person">
		<property name="id" value="9"></property>
		<property name="car">
			<!-- 内部bean ,不能被外部使用 -->
			<bean id="car02" class="com.webcode.pojo.Car"  p:name="内部car" p:carNo="京B123422" />
		</property>
	</bean>

测试代码:

        @Test
	public void test9() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) applicationContext.getBean("p9");
		System.out.println( person );
		System.out.println( applicationContext.getBean("car02") );
	}

打印结果:

常见错误:内部的Bean不能被外部使用

12、IOC之List属性的赋值

实验10:使用list子元素为List类型的属性赋值

Person对象

配置的信息:

        <bean id="p10" class="com.webcode.pojo.Person">
		<property name="id" value="9"></property>
		<property name="list">
			<!-- list标签,表示当前配置一个list集合 -->
			<list>
				<value>文</value>
				<value>星</value>
				<value>念</value>
			</list>
		</property>
	</bean>

------------------------------------------  此处省略测试代码!

打印结果

13、IOC之Map属性的赋值

实验11:使用map子元素为Map类型的属性赋值

配置信息:

        <!-- 实验11:使用map子元素为Map类型的属性赋值 -->
	<bean id="p11" class="com.webcode.pojo.Person">
		<property name="id" value="9"></property>
		<property name="map">
			<!-- map标签,表示当前配置一个map集合 -->
			<map>
				<entry key="key1" value="远方"></entry>
				<entry key="key2" value="流星"></entry>
				<entry key="key3" value-ref="car"></entry>			
			</map>
		</property>
	</bean>

------------------------------------------  此处省略测试代码!

打印结果:

14、IOC之Properties属性的赋值

实验12:使用prop子元素为Properties类型的属性赋值

配置信息:

        <!-- 实验12:使用prop子元素为Properties类型的属性赋值 -->
	<bean id="p12" class="com.webcode.pojo.Person">
		<property name="id" value="9"></property>
		<property name="map">
			<!-- props标签,表示当前配置一个Properties -->
			<props>
				<prop key="user">root</prop>
				<prop key="password">123456</prop>
			</props>
		</property>
	</bean>

------------------------------------------  此处省略测试代码!

打印结果:

15、IOC之util 名称空间

util名称空间,可以定义

实验13:通过util名称空间创建集合类型的bean

配置信息:

        <!--  util名称空间引用,可以定义
		实验13:通过util名称空间创建集合类型的bean-->
		<!-- 定义一个list集合 -->
	<util:list id="list1">
		<value>string1</value>
		<value>string2</value>
		<value>string3</value>	
	</util:list>	
	<bean id="p13" class="com.webcode.pojo.Person">
		<property name="id" value="13"></property>
		<property name="name" value="旻"></property>
		<property name="age" value="24"></property>
		<property name="phone" value="1722235896"></property>
		<!-- list对象 ref表示引用 -->
		<property name="phones" ref="list1"></property>
	</bean>

测试代码:

        @Test
	public void test13()throws Exception{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) applicationContext.getBean("p13");
		System.out.println( person );
		
		List<String> list = (List<String>) applicationContext.getBean("list1");
		System.out.println(list);
	}

打印结果:

图解:

16、IOC之级联属性赋值

实验14:给bean的级联属性赋值

配置:

        <!-- 实验14:给bean的级联属性赋值	 
			常见错误:
		级联属性一定要先注入对象。再注入对象的属性
	-->
	<bean id="p14" class="com.webcode.pojo.Person">
	 	<property name="id" value="14"></property>
	 	<property name="name" value="星"></property>
	 	<property name="age" value="27"></property>
	 	<property name="phone" value="17889652345"></property>
	 	<!-- list对象 ref 表示引用 -->
	 	<property name="car" ref="car"></property>
	 	<!-- -级联属性 -->
	 	<property name="car.name" value="凯迪拉克"></property>
	</bean>

------------------------------------------  此处省略测试代码!

打印结果:

常见错误:

级联属性一定要先注入对象。再注入对象的属性

图解:

17、IOC之静态工厂方法创建Bean

实验15:配置通过静态工厂方法创建的bean

代码:

    public class PersonFactory {
	public static Person createPerson() {
		return new Person(1, "我是静态工厂方法创建出来的", 18, "18688886666");
	}
    }

配置信息:

        <!-- 静态工厂方法调用创建对象	
			factory-method 是指调用哪个方法返回对象 -->
	
	<bean id="p15" class="com.webcode.pojo.factory.PersonFactory"
		factory-method="createPerson"/>

------------------------------------------  此处省略测试代码!

图解:

不重写toString方法的情况下,地址值相同,调用的是同一个对象,从工厂中的方法获取

创建对象流程:

18、IOC之工厂实例方法创建Bean

实验16:配置通过实例工厂方法创建的bean

    public class PersonFactory {

	public Person createPerson2() {
		return new Person(1, "我是工厂实例方法创建出来的", 18, "18688886666");
	}
	
    }

配置信息:

        <!-- 配置工厂实例 -->
	<bean id="personFactory" class="com.webcode.pojo.factory.PersonFactory"/>
	<!-- 
		factory-bean="personFactory" 	表示准备调用哪个实例的方法
		factory-method="createFacroty2"  是指调用哪个方法  	
	 -->
	 <bean id="p16" factory-bean="personFactory" factory-method="createPerson2">            </bean>
	

------------------------------------------  此处省略测试代码!

打印结果:

流程图解:

19、IOC之FactoryBean接口方式创建对象

实验17:配置FactoryBean接口创建Bean对象

FactoryBean接口方式

package com.webcode.pojo.factory;
import org.springframework.beans.factory.FactoryBean;
import com.webcode.pojo.Person;
    public class PersonFactoryBean implements FactoryBean<Person> {	
	/*
	 * 创建对象实例的适合,调用的方法
	 * */
	@Override
	public Person getObject() throws Exception {		
		return new Person(1,"我是PersonFactoryBean类",18,"14568526666");
	}	
	/*
	 * 返回对象的类型,相当于class属性
	 * */
	@Override
	public Class<?> getObjectType() {		
		return Person.class;
	}	
	/*
	 * 是否是单例
	 * */
	@Override
	public boolean isSingleton() {
		return true;
	}		
}

配置信息:

        <!-- 
		创建一个工厂实例对象FactoryBean接口的实现类
	 -->
	<bean id="p17" class="com.webcode.pojo.factory.PersonFactoryBean"/>

------------------------------------------  此处省略测试代码!

打印结果:

图解流程:

20、IOC之继承Bean配置

实验18:通过继承实现bean配置信息的重用

配置信息:

        <!-- 实验18:通过继承实现bean配置信息的重用 -->
		<bean id="parent" class="com.webcode.pojo.Person">
		<property name="id" value="100"></property>
		<property name="name" value="我思念的人啊"></property>
		<property name="age" value="24"></property>
		<property name="phone" value="1477888999"></property>	
	</bean>
	<!-- parent="parent" 继承指定的parentid的bean对象的配置信息-->
	<bean id="p18" class="com.webcode.pojo.Person" parent="parent">
		<property name="id" value="18"></property>
	</bean>

------------------------------------------  此处省略测试代码!

打印结果:

图解:先比较parent与id是否相同,再拿class进行比较,

注意:当有两个id相同,而类型不同的bean存在时,会出现ReaderContext.error读取异常

 

猜你喜欢

转载自blog.csdn.net/weixin_42405670/article/details/83048086