spring之IOC的初步使用

1.创建Student类
2.创建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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
    
    <bean id="stu" class="com.bean.Student">//从容器中取Student对象就是通过id取
    	
    </bean>
</beans>

3.编写测试类

@Test
	public void create() {
		String path="com/ioc/set_1/set.xml";
		ApplicationContext ioc = new ClassPathXmlApplicationContext(path);//获取IOC容器
		Student stu = (Student)ioc.getBean("stu");//从容器中取出对象
		System.out.println(stu);
	}

这就是简单的IOC容器的使用方法了,那么一些特殊情况应该怎么处理呢?

一、为对象注入属性

<bean id="stu2" class="com.bean.Student">
    	<property name="id" value="10"></property>
    	<property name="name" value="tom"></property>
    	<property name="age" value="11"></property> 	
</bean>

使用property标签,name是属性名,value就是属性值。那如果属性值是对象怎么办呢?

<bean id="tea" class="com.bean.Teacher">
    	<property name="id" value="11"></property>
    	<property name="name" value="jack"></property>
    	<property name="student" ref="stu2"></property>
    </bean>

如果属性值是对象,id不变,依然为属性名,value改成ref,ref里面的值填写为对应对象在ioc容器里面的id。

二、向对象注入集合
前面解决了基本数据类型,字符串,自定义对象的属性赋值,那么如果是list,set,map集合和Properties应该怎么注入呢。
如果是基本数据类型

<bean id="stu" class="com.bean.Student">
    	<property name="name" value="tom"></property>
    	<property name="list">//list集合
    		<list value-type="">//value-type中可以指定泛型的类型,如果不需要就不用写value-type
    			<value>10</value>
    			<value>tom</value>
    		</list>
    	</property>
    	<property name="set">//set集合
    		<set>
    			<value>123</value>
    			<value>tom</value>
    		</set>
    	</property>
    	<property name="map">//map集合
    		<map>
    			<entry key="name" value="tom"></entry>
    			<entry key="age" value="1"></entry>
    			<entry key="gender" value="男"></entry>
    		</map>
    	</property>
    	<property name="prop">//properties
    		<props>
    			<prop key="tom">123</prop>
    			<prop key="age">111</prop>
    			<prop key="gender"></prop>
    		</props>
    	</property>
    </bean>

如果list和set集合中的是引用数据类型,只需要把value标签换成ref标签即可,如果map集合中的key和value为对象,那么key和value可以换成key-ref和value-ref。

三、使用构造器注入数据
前面我们都是利用set方法注入的值,那么是否可以使用构造器注入值呢?当然可以

<bean id="stu" class="com.bean.Student">
    	<constructor-arg index="0" type="long" value="22"></constructor-arg>
    	<constructor-arg index="1" type="java.lang.String" value="tom"></constructor-arg>
</bean>

index代表的是构造器中属性的下标,这里我们调用的是new Student(long id,String name)的构造器,index="0"代表是id属性,type代表属性的类型,value就是属性的值,同样如果属性的值是对象,那么value改成ref即可,ref中填写bean对象的id。

四、自动注入
每次写一个bean对象,如果对象里面还有一个对象属性,都要写一遍,这样就太麻烦了,有没有什么简单的方法呢?有,这就是自动注入,从当前ioc容器获得一个对象,注入到当前ioc容器的另一个bean对象中。

<bean id="student" class="com.bean.Student">
	<property name="id" value="1"></property>
	<property name="name" value="jack"></property>
	<property name="prop">
		<props>
			<prop key="tom">123</prop>
		</props>
	</property>
</bean>	
<bean id="tea" class="com.bean.Teacher" autowire="byName">
	<property name="name" value="老师"></property>
</bean>

当前Teacher类中有Student类型的属性,使用autowire,就可以把当前ioc容器中的Student类型的属性注入到Teacher对象中
注意:byName和byType区别,byName主要是根据ioc中对象的id和Teacher中Student类的属性名来查找,找到一致的就注入,byType是查找ioc中类型和Teacher中Student类一致的,一致的就注入。

五、容器中对象的生命周期
单例对象
1.创建
在容器创建的时候就创建了所有的对象(单例)
可以修改为非单例(bean scope = “prototype”)

2.初始化
创建完成立刻初始化 bean标签中可以写init-method=‘方法名’,此时会立刻执行这个初始化方法

3.执行
从容器中获取出来就执行

4.销毁
当容器销毁的时候就销毁,如何销毁容器呢?
ioc.destroy();容器中的所有单例对象都会被销毁

非单例对象
1.创建
获取的时候创建,创建完立刻初始化并且执行
2.销毁
容器不管理

六、使用多个xml文件创建容器

String[] path ={"xxx.xml","xxxx.xml"};
ApplicationContext ioc = new ClassPathXmlApplicationContext(path);

xml文件中的对象可以互相引用。
但是一般我们不推荐这么做,因为后期如果要加xml文件要重新动java文件,我们一般在xml文件中使用import标签引入其他xml文件

七、工厂
创建一个LT类,实现序列化接口

public class LT implements Serializable{
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

创建一个LTFactory类,实现FactoryBean接口,实现里面的方法

public class LTFactory implements FactoryBean<LT>{

	@Override
	public LT getObject() throws Exception {
		
		return new LT();
	}

	@Override
	public Class<?> getObjectType() {
		return LT.class;
	}

	@Override
	public boolean isSingleton() {
		return false;
	}
	
}

在xml文件中注入LTFactory,此时创建ioc容器,从ioc容器中获取的是LT对象,而非LTFactory对象。

如果不通过实现接口的方式,来定义这么一个工厂类,应该怎么做呢?
比如我这个类,返回的是一个LT对象

public class LGM {
	public LT getLT(){
		return new LT();
	}
}

那么在xml文件中要这么配置,第一个配置LGM,但是只这样调用容器返回的还是LGM对象,而不是LT对象,我们需要让spring知道这是一个工厂类对象,就需要用factory-bean指定工厂对象在ioc容器中的id,factory-method指定工厂类对象生成LT的方法。一个工厂对象可以创造多个对象,只需要多个配置即可。

<bean id="lgm" class="com.ioc.instanceFactory_9.LGM"></bean>
<bean id="foc" factory-bean="lgm" factory-method="getLT"></bean>

八、静态工厂
因为静态方法只需要类就能调用,所以和上面的相比只需要一个bean标签,因为本身就是一个工厂,所以不需要factory-bean

<bean id="foc" class="com.ioc.staticFactory_10.XM" factory-method="getLT"></bean>

九、发布事件
定义一个类继承ApplicationEvent类

public class Myevent extends ApplicationEvent{

	public Myevent(Object source) {
		super(source);
		// TODO Auto-generated constructor stub
	}
	
}

定义一个Listener实现ApplicationListener接口,
监听ioc容器中的事件

public class MyListener implements ApplicationListener<Myevent>{//泛型是要监听的事件

	@Override
	public void onApplicationEvent(Myevent arg0) {
		// TODO Auto-generated method stub
		System.out.println("11");
	}
}

在xml文件中配置监听器

<bean class="com.ioc.event_12.MyListener"></bean>

十、注解!!!十分重要
如何使用注解进行配置
@Component:写在类名上,把类对象放到ioc容器中,相当于bean标签
@Autowired:写在属性上,构造器上,set方法上,从当前容器获取对象注入进来。(寻找方式:先使用byType,找到多个再byName)
在xml文件中配置注解所在的包,读取注解

<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.ioc.annotation_13"></context:component-scan>

但是这种方式还是要在xml文件中配置,可以不用吗?当然可以~

我们之前都是使用ApplicationContext ioc = new ClassPathXmlApplicationContext(path);的形式创建容器,换成使用AnnotationConfigApplicationContext创建ioc容器

创建一个JavaConfig类

@Configuration//这个注解表面这是一个配置类
@ComponentScan("com.ioc.annotation_13")//扫描这个包下的注解
public class MyConfig {
	
}

测试类

@Test
	public void test() {
		AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(MyConfig.class);
		System.out.println(ioc.getBean("boss"));
	}

这时候就不需要xml文件了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值