Spring(一)控制反转和依赖注入

1. Spring介绍

Spring的两大核心:控制反转(IOC)和面向切面(AOP);

2、控制反转(IOC)

控制反转和依赖注入(DI)同时使用,下面介绍为什么要使用这两个东东

当没有Spring时,我们使用Java编程,创建一个对象,可能需要下面这样:

package Test;

public class Learn01 {
	private Say ss;
	Learn01()
	{
		ss = new Say();
	}
	public void doo()
	{
		ss.say();
	}
	public static void main(String[] args)
	{
		Learn01 ll = new Learn01();
		ll.doo();
	}
}

class Say {
	public void say()
	{
		System.out.println("Class Say... Func: say");
	}
}

这里面最大的问题是,Learn01类对Say产生了依赖,因为在Learn01内部创建了对象,做单元测试时,不利于测试,无法构造多种Say对象;

为了解决Learn01对Say的依赖问题,代码可能整改成这个样子:

package Test;

public class Learn01 {
	private Say ss;
	
	public Say getSs() {
		return ss;
	}
	public void setSs(Say ss) {
		this.ss = ss;
	}
	public void doo()
	{
		ss.say();
	}
	public static void main(String[] args)
	{
		Learn01 ll = new Learn01();
		Say ss = new Say("Hello World");
		ll.setSs(ss);
		ll.doo();
	}
}

class Say {
	private String message;
	public Say(String msg)
	{
		message = msg;
	}
	public void say()
	{
		System.out.println("Class Say... Func: say " + message);
	}
}

代码修改成这个样子,可以满足了 Learn01类和Say的依赖关系,但是Say类已经在硬编码中message已经写死为hello world,如果再想修改,就需要全篇代码去找,再全部修改过来;

于是,又有同学说,那我单独封装一个工厂类,用来创建这个对象:

package Test;

public class Learn01 {
	private Say ss;
	
	public Say getSs() {
		return ss;
	}
	public void setSs(Say ss) {
		this.ss = ss;
	}
	public void doo()
	{
		ss.say();
	}
	public static void main(String[] args)
	{
		Learn01 ll = new Learn01();
		Say ss = (Say)Factory.create("Say");
		ll.setSs(ss);
		ll.doo();
	}
}

class Say {
	private String message;
	public Say(String msg)
	{
		message = msg;
	}
	public void say()
	{
		System.out.println("Class Say... Func: say " + message);
	}
}

class Factory
{
	public static <E> E create(String clsName)
	{
		return (E)new Say("Hello World");
	}
}

代码修改成这个样子以后,只要修改Factory中一处的内容即可,不需要全篇去修改代码了,解决了依赖问题。

理解了依赖的问题,下面说说Spring的控制反转,像Factory类一样,Learn01中想使用Say对象,本来应该自己创建,自己维护,现在变为Factory来创建和维护,自己作为一个使用者,控制权发生了反转,这就是控制反转;依赖注入可以理解为,Learn01依赖Say对象,我们可以通过Say注入到Learn01中,注入方式:

1. 构造函数注入

2. setter方法注入

3. Spring实现

1、下面spring库

https://repo.spring.io/release/org/springframework/spring/

2、在Eclipse中加入Spring所需要的库文件

3、在src目录下,创建beans.xml文件,实现setter方法注入:

<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-3.0.xsd">

   <bean id="learn01" class="Test.Learn01">
       <property name="ss" ref="say"/>
   </bean>
   <bean id="say" class="Test.Say">
       <property name="message" value="Hello Axt0810"/>
   </bean>

</beans>

  说明:bean id用来唯一标识初始化的类,property是根据name的setter方法来进行注入,如果是参数,直接写value=xxx,如果是类,则用ref=xxx_id

package Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Learn01 {
	private Say ss;
	public void setSs(Say ss) {
		this.ss = ss;
	}
	public void doo() {
		ss.say();
	}
	public static void main(String[] args) {
		ApplicationContext context = 
	             new ClassPathXmlApplicationContext("beans.xml");
		Learn01 ll = (Learn01)context.getBean("learn01");
		ll.doo();
	}
}

package Test;

public class Say {
	private String message;
	
	public void say(){
		System.out.println("Class Say... Func: say " + message);
	}
	
	public void setMessage(String message) {
		this.message = message;
	}
}

main函数中,通过ClassPathXmlApplicationContext方法,读取xml中内容,通过getBean创建bean

4、构造方法注入

<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-3.0.xsd">

   <bean id="learn01" class="Test.Learn01">
       <property name="ss" ref="say"/>
   </bean>
   <bean id="say" class="Test.Say">
   	<constructor-arg value="Hello Axt"></constructor-arg>
   </bean>

</beans>
package Test;

public class Say {
	private String message;
	
	public Say(String message) {
		super();
		this.message = message;
	}

	public void say(){
		System.out.println("Class Say... Func: say " + message);
	}
	
	public void setMessage(String message) {
		this.message = message;
	}
}

5、集合类型注入

List:

<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-3.0.xsd">

   <bean id="learn01" class="Test.Learn01">
       <property name="ss" ref="say"/>
   </bean>
   <bean id="say" class="Test.Say">
   	<constructor-arg>
   		<list>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
   		</list>
   	</constructor-arg>
   </bean>

      <property name="addressSet">
         <set>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
        </set>
      </property>
        
        # key和value为任意类型
        <map>
            <entry key="1" value="INDIA"/>
            <entry key="2" value="Pakistan"/>
            <entry key="3" value="USA"/>
            <entry key="4" value="USA"/>
         </map>

       # key和value为String
      <property name="addressProp">
         <props>
            <prop key="one">INDIA</prop>
            <prop key="two">Pakistan</prop>
            <prop key="three">USA</prop>
            <prop key="four">USA</prop>
         </props>
      </property>

    # 当值为对象
    <constructor-arg>
   		<list>
			<ref bean="e1"/>
			<ref bean="e2"/>
   		</list>
   	</constructor-arg>
   </bean>
	<bean id="e1" class="Test.Elem">
	</bean>
	<bean id="e2" class="Test.Elem">
	</bean>

    <constructor-arg>
   		<map>
   			<entry key-ref="e1" value-ref="e2" />
   		</map>
   	</constructor-arg>
</beans>

猜你喜欢

转载自blog.csdn.net/axt0810/article/details/84995055