Spring 2:IOC

※ 1. Spring IOC(must):
※ IOC:Inversion of Control 控制反转
       一种说法:对象之间的依赖关系,由容器在运行时依据配置文件动态的建立
       另一种说法:对象的控制器转移了,转到外部容器了,避免了代码的纠缠,代码更
       容易被维护,模板之间的耦合性降低,容易测试
IoC 控制反转意味着将你设计好的类交给容器去控制,而不是在类的内部进行控制,即控制权由
应用代码中转到了外部容器
   IoC:包括两部分内容
  ※ DI:Dependency Injection依赖注入

组件不做定位查询,只提供相应方法,由容器创建对象,并调用相应方法设置所需对象需要的组件

第三方(Spring)
2.你需要什么(将需要的写成全局变量)
3.怎么放入(给全局变量赋值:1.set方法,2.构造器)

1.程序自身
    我是谁(告诉Spring:全包名+类名)

xml

<bean class=“com.briup.UserService”>//指明service
  <property name=“dao” ref=“da”/>//需要dao
</bean>
<bean name=“da” class=“com.briup.UserDao”>//指明dao

注意:servlet是由Tomcat构建的,不能通过这种方式指明(框架的整合,有servlet与service结合的jar包)(写注解方式)


   ※ (不要求)DL:Dependency Lookup依赖查找

容器创建对象并提供回调接口和上下文环境给组件,需要时通过接口从容器中查找对象
    依赖查找,现在使用不太多。(EJB使用的更多,将对象创建好后,放到容器中。)

Spring IOC:依赖查找(主动的找)


高内聚,低耦合
解决依赖问题:(建立工厂)

public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";
   public static Object getBean(String msg){
      if(msg=="service"){
        new  Service();
      }else{
        new Dao();
      }
   }
}


调用时不再new对象

Class RegisterSer{

doGet(){
String name=Request.getParameter(“name”)
String passwd=Request.getParameter(“passwd”)
…
 UserService ser=BeanFactory.getBean(BeanFactory.SERVICE);
ser.register(name,passwd…);
    }
}

//service层
Class UserService{
public void register(String name,String passwd…){
…
UserDao dao=BeanFactory.getBean(BeanFactory.DAO);
dao.saveUser(name,passwd…);
     } 
}

//dao层
Class UserDao{
saveUser(String name,String passwd…);

}


构建配置文件(pro.properties) 维护全包名类名
方法一:静态代码块
dao=com.briup.Dao.UserDao
service=com.briup.Service.UserService


public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";
   
   static Properties pro=null;
   static {
       pro=new Properties();
       pro.load(new FileNputStream(new File("pro.perties")));
   }
   public static Object getBean(String msg){
      if(msg=="service"){
        Class.forName(pro.getProgerty("service")).newInstance();
      }else{
        Class.forName(pro.getProgerty("dao")).newInstance();
      }
   }
}


方法二:静态方法
public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";

   public static Properties getPro(){
       if(pro==null){
         pro=new Properties();
         pro.load(new FileNputStream(new File("pro.perties")));
        }
       return pro;
   }
   public static Object getBean(String msg){
      getPro();
      if(msg=="service"){
         Class.forName(pro.getProgerty("service")).newInstance();
      }else{
         Class.forName(pro.getProgerty("dao")).newInstance();
      } 
   }
}


更改dao和service时,只用更改properties文件中的value(全包名)值。


    IOC解决:对象谁来创建的问题
    DI解决:对象间的关系如何建立的问题。
 org.springframework.beans及org.springframework.context包是IOC容器的基础
=================================================
※ 2. SpringIOC核心API - BeanFactory接口和容器
   BeanFactory是Spring中Bean容器,IoC的核心接口,主要用于处理Bean的初始化和配置,
   建立对象间的依赖关系
   定义了如下方法:
  

   Object getBean(String name) //根据指定名称返回一个Bean实例

   <T> T getBean(Class<T> requiredType)  
                              //返回一个与给定Class唯一匹配的Bean实例

   <T> T getBean(String name, Class<T> requiredType)

   Object getBean(String name, Object... args)

   Class<?> getType(String name)       //得到名称为name的Bean的Class对象
   
   boolean isPrototype(String name)   //判断名称为name的Bean是否是原型,
                                          即是否总是返回一个新实例
   boolean isSingleton(String name)   //判断名称为name的Bean是否是单例

   boolean containsBean(String name)  //判断是否包含给定名称的Bean实例

   boolean isTypeMatch(String name, Class<?> targetType)
                         //判断名称为name的Bean实例是否为targetType类型
   String[] getAliases(String name)  //如果名称为name的Bean有别名返回
   


   通过getBean方法便可以得到相应的类实例,但是最好永远不调用,而使用注入,
   避免对Spring API的依赖
   
   在Spring中,同一Spring容器中的bean默认情况下是Singleton(单例),将在bean
   的作用域介绍.

ApplicationContext接口
   该接口继承于BeanFactory,增强了BeanFactory,提供了事务处理AOP,国际化,事件传递

1.接口型Dao,Service
bean包:

package com.briup.bean;

public class UserDao {

}

package com.briup.bean;

public class UserService {
 private UserDao dao;
public UserService() {
	System.err.println("-------");
}
 public UserService(UserDao dao) {
	 this.dao=dao;
 }
public UserDao getDao() {
	return dao;
}

public void setDao(UserDao dao) {
	this.dao = dao;
}
 
}

IOC包:

<?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构建对象
       name指的是构建对象的名字
       class指向构建对象的全限定名
       us=Class.forName("com.briup.bean.UserService").newInstance();
       
       scope属性:控制的是对象创建的是不是单例对象 
          prototype 原类型(非单例)
          singleton 默认单例-->
     <bean name="us" class="com.briup.bean.UserService"
     scope="prototype">
       <!-- property决定给当前对象设置属性的方式采用set拼接name属性setDao() 
            参数是基本数据类型value属性指明,
            对象用ref指明-->
       <property name="dao" ref="ud"></property>
     </bean>
     <bean name="ud" class="com.briup.bean.UserDao"></bean>
  </beans>

测试类:


 @Test
 public void ioc_test() {
	 try {
		//启动Spring容器,加载配置文件,构建对象
		 ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext("com/briup/IOC/ioc.xml");
		 //getBean()方法从容器中获取对象
		 //默认情况下Spring构建的都是单例对象
		 UserService ser=(UserService) cp.getBean("us");
		 UserService ser1=cp.getBean(UserService.class);
		 UserService ser2=cp.getBean("us",UserService.class);
		 System.out.println(ser);
		 //isPrototype判断Spring容器中对象是不是原类型
		 System.out.println(cp.isPrototype("us"));//true
		 System.out.println(cp.isPrototype("ud"));//false
		 //isSingleton判断Spring容器中对象是不是单例对象
		 System.out.println(cp.isSingleton("us"));//false
		 System.out.println(ser.getDao());
		 System.out.println(cp.getBean("ud"));
		 //System.out.println(ser1);
		 //System.out.println(ser2);
	} catch (BeansException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
 }

=================================================
※ 3. 配置文件
配置Spring通过读取配置元数据来对应用中各个对象进行实例化,配置以及组装,通常使用
XML文件来作为配置元数据的描述格式
   可以将XML配置分别写在多个文件中   可以将多个配置放在一个String数组中传递给容器进行初始化
     

   eg: ApplicationContext ac = new ClassPathXmlApplicationContext(
            new String[]{"services.xml","daos.xml"})
   也可以在XML中使用<import resource="" />来进行导入

   XML基本结构如下:
   <?xml version="1.0" encoding="UTF-8"?>
   <beans xmlns=".....">
      <bean id=".." class="..." >
         <property name="..." ... />
      </bean>
      ...
   </beans>

容器的初始化和ClassPathXmlApplicationContext
   ClassPathXmlApplication实现ApplicationContext,用于读取Xml初始化上下文,初始化方法如下:
      ApplicationContext ac = new ClassPathXmlApplicationContext(".../path/beans.xml");
   与Hibernate类似,不同的是Spring没有默认的配置文件

=================================================
※ ※ 4.  IOC注入(需要,第三方容器给你)
1)setter方式(必须依靠无参构造器)
      A、基本类型(8中基本类型+字符串)的装配
      B、对象类型的装配
      C、集合的装配

类中是基本数据类型
set方式
Value属性给基本数据类型赋值(String)
<property name=“” value=“”>

类中有类类型
class UserService{
UserDao dao}
ref为属性值的是bean对象构建类类型的名字
<property name=“dao” ref=“tt”>

<property name=“dao”>
<ref bean=“tt”/>
</property>

<property name=“dao”>
<bean class=“UserDao”>
</property>

<bean name=“tt” class=“UserDao”>
2.实体类型Student
bean包

package com.briup.bean;

public class Student {
private long id;
private String name;
private int age;
private String email;
public long getId() {
	return id;
}
public void setId(long id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public int getAge() {
	return age;
}
public void setAge(int age) {
	this.age = age;
}
public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}
@Override
public String toString() {
	return "Student [id=" + id + ", name=" + name + ", age=" + age + ", email=" + email + "]";
}

}

IOC包配置文件:

<?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">
          <!-- name属性指的是Spring中储存对象的名字,scope="prototype"设置单例对象时,不同名字构建的对象仍不同
               name可以指向多个名字,中间逗号隔开
               id标签也是指的是Spring中储存对象的名字,不能用逗号,
               id中的名字是一个整体
                -->
          <bean id="student" name="stu,stu1,stu2" class="com.briup.bean.Student" scope="prototype">
          <!-- 1.构建对象
               2.设置属性
                 setId   反射getDeclaredMethod("setId")
                         方法镜像public void setId(long);
                         方法参数getParameterTypes()[long]
                         long id=Long.parseLong("1");
                         stu.setId(id);
           -->
          <property name="id" value="1"></property>
           <property name="name" value="tom"></property>
            <property name="age">
            <value>33</value>
            </property>
             <property name="email" value="12@qq.com"></property>
          </bean>
          <!-- 给某个名字对应对象起别名 -->
          <alias name="stu" alias="studd"/>
          </beans>
测试类:

@Test
	public void setter_test() {
		 ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext("com/briup/IOC/setter.xml");
		 System.out.println(cp.getBean("stu"));
		 System.out.println(cp.getBean("stu1"));
		 System.out.println(cp.getBean("stu2"));
		 System.out.println(cp.getBean("student"));
	}

 

A. 基本类型的装配
注意: 用setter方式注入的话,必须要用set、get方法
方式: 配置元素<value/>

例子:
public class HelloBean {
private String name;
private int age;
public String sayHello(){
return "hello "+name +",your age is" + age;
}
.............
}
配置文件applicationContext.xml
<bean id="helloBean" class="ioc.HelloBean">
<property name="name">
<value>terry</value>
</property>
<property name="age" value="20">
</property>
</bean>
<!--id是Bean的唯一标识,要求在整个配置文件中要唯一,也可使用name属性
,bean标签里面的id和name属性都可以用来标识这个配置的对象,
 -->
<!--property 对于所有用setter方式来注入的必须用Property来指定-->
<!--value 是对以基本类型,都用value来注入,可以实现自动的数据类型转换-->
测试类:
public class Test {
public static void main(String[] args) {
ApplicationContext ac =
 new ClassPathXmlApplicationContext("ioc1applicationContext.xml");
//获取容器的一个实例
HelloBean hb = (HelloBean) ac.getBean("helloBean");
System.out.println(hb.sayHello());
}
}


 B. 对象类型的装配
  (1)、<ref local=" "/>
  (2)、<ref bean=" "/>
  (3)、使用property的ref属性引用
 

public class OtherBean {
private String str1;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String toString(){
return "OtherBean "+str1;
}
}
public class SomeBean {
private OtherBean ob;
public void printInfo(){
System.out.println("someBean "+ob);
}
public OtherBean getOb() {
return ob;
}
public void setOb(OtherBean ob) {
this.ob = ob;
}
}
配置applicationContext.xml
<bean id="someBean" class="ioc.SomeBean">
<property name="ob">
<ref bean="otherBean" />
</property>
</bean>
配置other.xml文件
 <bean id="otherBean" class="ioc2.OtherBean">
<property name="str1">
<value>string1</value>
</property>
</bean>
测试类:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"ioc2//applicationContext.xml","ioc2//other.xml"});
SomeBean sb = (SomeBean) ac.getBean("someBean");
sb.printInfo();
}
rel.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.xsd">
  <!-- <bean name="us" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    1.porperty内属性ref引入对象的名字(spring)
    <property name="dao" ref="dap"></property>
  </bean> -->
  <bean name="us" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    <!-- ref引入对象的名字(spring) -->
    <property name="dao" >
    <!-- 2.ref便签 -->
     <ref bean="dap"/>
     <!--有些版本(低)也支持  
     <ref local="dap"/> -->
    </property>
  </bean>
  <bean name="us1" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    <!-- 3.ref引入对象的名字(spring) -->
    <property name="dao">
    <!-- bean标签 -->
    <bean name="dap" class="com.briup.bean.UserDao"></bean>
    </property>
  </bean>
  
  <bean name="us2" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" ref="str"></property>
    <property name="dao">
    <bean name="dap" class="com.briup.bean.UserDao"></bean>
    </property>
  </bean>
  <bean name="str" class="java.lang.String">
    <!-- 基于构造器方式注入
    index表示该参数在当前对象构造器中的位置,角标从0开始 
    Class.forName("java.lang.String").newInstance("test")-->
    <constructor-arg index="0" value="test"></constructor-arg>
    </bean>
  <bean name="dap" class="com.briup.bean.UserDao">
  
  </bean>
  
  </beans>

测试类:

@Test
	public void rel_test() {
		 try {
			ClassPathXmlApplicationContext cp=
					 new ClassPathXmlApplicationContext("com/briup/IOC/rel.xml");
			 UserService us=(UserService) cp.getBean("us2");
//			 UserService us1=
//			 cp.getBean("us",UserService.class);
			 System.out.println(us);
			 System.out.println(us.getName());
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

C. 集合的装配
方式:配置元素<list> <set> <map> <props>
 

public class SomeBean {
private List listProperty;
private Set setProperty;
private Map mapProperty;
private Properties<String,String> property;
public List getListProperty() {
return listProperty;
}
public void setListProperty(List listProperty) {
this.listProperty = listProperty;
}
public Set getSetProperty() {
return setProperty;
}
public void setSetProperty(Set setProperty) {
this.setProperty = setProperty;
}
public Map getMapProperty() {
return mapProperty;
}
public void setMapProperty(Map mapProperty) {
this.mapProperty = mapProperty;
}
public Properties getProperty() {
return property;
}
public void setProperty(Properties property) {
this.property = property;
}
public void printInfo(){
System.out.println("listProperty");
System.out.println(listProperty);
System.out.println("setProperty");
System.out.println(setProperty);
Set set = mapProperty.entrySet();
Iterator it = set.iterator();
while(it.hasNext()){
 Map.Entry entry = (Entry) it.next();
 System.out.println("Key " +entry.getKey() );
 System.out.println("value "+entry.getValue());
}
System.out.println("props: ");
Set set2 = property.entrySet();
Iterator it2 = set2.iterator();
while(it2.hasNext()){
Map.Entry entry= (Entry) it2.next();
System.out.println("key "+entry.getKey());
System.out.println("value "+entry.getValue());
}
}
}
applcationContext.xml的写法:
<bean id="someBean" class="ioc.SomeBean">
<property name="listProperty">
 <list>
    <value>list1</value>
    <value>list1</value>
    <value>list3</value>
 </list>
</property>
<property name="setProperty">
 <set>
    <value>set1</value>
    <value>set1</value>
    <value>set3</value>
 </set>
</property>
    <property name="mapProperty">
 <map>
    <entry key="key1">
          <value>value1</value>
    </entry>
   <entry key="key2">
          <value>value2</value>
    </entry>
 </map>
</property>
  <property name="property">
     <props>
  <prop key="key1">prop1</prop>
  <prop key="key2">prop2</prop>
  <prop key="key3">prop3</prop>
  </props>
</property>
</bean>
测试类:Test
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext  ac =
 new ClassPathXmlApplicationContext("ioc3applicationContext.xml");
    SomeBean sb = (SomeBean) ac.getBean("someBean");
    sb.printInfo();
}
实体类:

package com.briup.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class CollTest {
private String[] array;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
private Properties pros;
public String[] getArray() {
	return array;
}
public void setArray(String[] array) {
	this.array = array;
}
public List<String> getList() {
	return list;
}
public void setList(List<String> list) {
	this.list = list;
}
public Set<String> getSet() {
	return set;
}
public void setSet(Set<String> set) {
	this.set = set;
}
public Map<String, String> getMap() {
	return map;
}
public void setMap(Map<String, String> map) {
	this.map = map;
}
public Properties getPros() {
	return pros;
}
public void setPros(Properties pros) {
	this.pros = pros;
}

}


IOC配置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.xsd">
<bean name="str" class="java.lang.String">
  <constructor-arg index="0" value="array5"></constructor-arg>
</bean>
<bean name="coll" class="com.briup.bean.CollTest">
  <property name="array">
  <list>
  <value>array1</value>
  <value>array2</value>
  <value>array3</value>
  <ref bean="str"/>
  </list>
  <!-- 数组的装配 array,list标签都可以写-->
  <!-- <array>
    <value>array1</value>
    <value>array2</value>
    <value>array3</value>
    <ref bean="str"/>
    <bean class="java.lang.String">
      <constructor-arg index="0" value="array4"></constructor-arg>
    </bean>
  </array> -->
  </property>
  <property name="list">
  <!-- list集合的装配,spring默认构建的集合是ArrayList 
       在beans的scheme的约束下不能指定具体的构建什么样的集合,
       util的scheme可以自定义集合类型
       value-type指的是集合的类型-->
  <!-- <array value-type="java.lang.String">
  <value>list1</value>
   <value>list2</value>
    <value>list3</value>
  </array> -->
  <list>
  <value>list1</value>
   <value>list2</value>
    <value>list3</value>
  </list>
  </property>
  
  <property name="set">
  <!-- set集合的装配,标签选择set,默认构建的结合是LinkedHashSet -->
  <set value-type="java.lang.String">
  <value>set1</value>
   <value>set2</value>
    <value>set3</value>
    <ref bean="str"></ref>
  </set>
  </property>
  
  <property name="map">
  <!-- map集合的装配,默认构建的集合是LinkedHashMap
       map下的entry表示一组键值对内容
       entry属性  key表示键(基本数据类型或String)key-ref表示键是对象 key-ref指向做键的对象名字(存在Spring中)
       value表示基本数据类型的值(String)value-ref把Spring中某个名字的对象作为值 -->
  <map key-type="java.lang.String" value-type="java.lang.String">
  <entry key="key1" value="1"></entry>
   <entry key="key2" value="2"></entry>
    <entry key-ref="str" value-ref="str"></entry>
  </map>
  </property>
  
  <property name="pros">
  <!--properties集合的装配  -->
  <props value-type="java.lang.String">
  <prop key="pro1">pro1</prop>
  <prop key="pro2">pro2</prop>
  <prop key="pro3">pro3</prop>
  </props>
  
  </property>
</bean>
</beans>

测试类:

	public void coll_test() {
			ClassPathXmlApplicationContext cp=
					 new ClassPathXmlApplicationContext("com/briup/IOC/coll.xml");
			CollTest col=(CollTest) cp.getBean("coll");
			System.out.println(col);
//			String[] strs=col.getArray();
//			System.out.println(Arrays.toString(strs));
			
//			List<String> list=col.getList();
//			System.out.println(list.getClass());
//			System.out.println(list);
			
//			Set<String> sets=col.getSet();
//			System.out.println(sets.getClass());
//			System.out.println(sets);
			
//			Map<String, String> map=col.getMap();
//			System.out.println(map.getClass());
//			System.out.println(map);
			
			Properties pro=col.getPros();
			System.out.println(pro.getClass());
			System.out.println(pro);
		 }
2.加util标签库

配置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"
       xmlns:util="http://www.springframework.org/schema/util"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/util
          http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Spring容器构建集合对象 id标签表示集合的名字-->
<util:list id="strlist" list-class="java.util.LinkedList" value-type="java.lang.String">
<value>list1</value>
<value>list2</value>
<value>list3</value>
</util:list>
<bean name="de_coll" class="com.briup.bean.CollTest">
<property name="array">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<property name="list" ref="strlist">
<!-- list-class指定Spring构建list集合的类型 -->
<!-- <util:list list-class="java.util.LinkedList" value-type="java.lang.String">
<value>list1</value>
<value>list2</value>
<value>list3</value>
</util:list> -->
</property>
<property name="set">
<!-- set-class指定Spring构建的set集合对象 -->
<util:set set-class="java.util.HashSet" value-type="java.lang.String">
<value>set1</value>
<value>set2</value>
<value>set3</value>
</util:set>
</property>
<property name="map">
<util:map map-class="java.util.HashMap">
<entry key="1" value="te1"></entry>
<entry key="2" value="te2"></entry>
<entry key="3" value="te3"></entry>
<entry key-ref="str" value-ref="str"></entry>
</util:map>
</property>
<property name="pros">
<!-- <props>
<prop key="pro1">pro</prop>
<prop key="pro2">pro</prop>
<prop key="pro3">pro</prop>
</props> -->
<!-- location直接将properties文件的key=value内容加载到集合对象中,路径也是基于classpath(src的下一级目录开始) -->
<util:properties location="com/briup/IOC/db.properties"></util:properties>
</property>
</bean>

</beans>

测试类:
@Test
	public void de_coll_test() {
		try {
			//ClassPathXmlApplicationContext构造器内参数是可变参,可以写多个路径
//				ClassPathXmlApplicationContext cp=
//						 new ClassPathXmlApplicationContext("com/briup/IOC/definecoll.xml");
				ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext(new String[] {"com/briup/IOC/coll.xml","com/briup/IOC/definecoll.xml"});
				CollTest col=(CollTest) cp.getBean("de_coll");
				List<String> list=(List<String>) cp.getBean("strlist");
				System.out.println(list);
				System.out.println(col);
//			String[] strs=col.getArray();
//			System.out.println(Arrays.toString(strs));
				
//			List<String> list=col.getList();
//			System.out.println(list.getClass());
//			System.out.println(list);
				
//			Set<String> sets=col.getSet();
//			System.out.println(sets.getClass());
//			System.out.println(sets);
				
				Map<String, String> map=col.getMap();
				System.out.println(map.getClass());
				System.out.println(map);
				
//			Properties pro=col.getPros();
//			System.out.println(pro.getClass());
//			System.out.println(pro);
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 }

※ ※ 注:当ref=“”指向的bean对象,不在本xml文件内,也可以使用,但是在测试时,必须指明使用的是哪个文件的,路径都需要写。

例:如上面代码中
definecoll.xml文件中value-ref调用coll.xml文件中的str对象

<util:map map-class="java.util.HashMap">
<entry key="1" value="te1"></entry>
<entry key="2" value="te2"></entry>
<entry key="3" value="te3"></entry>
<entry key-ref="str" value-ref="str"></entry>
</util:map>

coll.xml文件

<bean name="str" class="java.lang.String">
  <constructor-arg index="0" value="array51"></constructor-arg>
</bean>
<bean name="coll" class="com.briup.bean.CollTest">

测试类中:

ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext(new String[] {"com/briup/IOC/coll.xml","com/briup/IOC/definecoll.xml"});
				CollTest col=(CollTest) cp.getBean("de_coll");

路径问题:需要到哪个xml文件中的bean对象,就需要将路径给出构建bean对象,由于ClassPathXmlApplicationContext()方法参数是可变参,所以路径逗号隔开。


2)基于构造器

方式: 配置<constructor-arg>元素
在Bean中不用写set方法,但是要有相应的构造器

重载:个数,类型,顺序
 

<constructor-arg type="int" value="">
<constructor-arg  index="0" value="">
例子:
public class SomeBean {
//构造器配置
private String str1;
private String str2;
private int value1;
public SomeBean(String str1, String str2, int value1) {
super();
this.str1 = str1;
this.str2 = str2;
this.value1 = value1;
}
public void printInfo(){
   System.out.println("str1 "+str1 +"str2 "+str2+" value1 "+value1 );
}
}
配置文件applicationContext.xml的写法
<bean id="someBean" class="ioc.SomeBean">
方式一:使用类型注入
<constructor-arg type="java.lang.String">
  <value>String1</value>
</constructor-arg>
<constructor-arg type="java.lang.String" value="String2">
</constructor-arg>
<constructor-arg type="int">
  <value>100</value>
</constructor-arg>
方式二:使用参数的索引注入
<constructor-arg index="1"> <!--表示第二个参数-->
  <value>String1</value>
</constructor-arg>
<constructor-arg index="0">
</constructor-arg>
<constructor-arg index="2">
  <value>100</value>
</constructor-arg>
</bean>
配置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.xsd">
        <!-- 基于构造器给Spring构建的对象传参,使用的子标签constructor-arg-->
<bean name="stu" class="com.briup.bean.Student">
<!-- 1.基于角标传参数,角标从0开始,角标代表的是赋值的位置
     配置constructor-arg位置不会影响赋值 -->
    <constructor-arg index="0" value="11"></constructor-arg>
    <constructor-arg index="1" value="tom"></constructor-arg>
    <constructor-arg index="2" value="30"></constructor-arg>
    <constructor-arg index="3" value="121@qq.com"></constructor-arg>
</bean>
<!-- 2.基于构造器参数的类型配置 
     基本数据类型直接写类型-->
<bean name="stu1" class="com.briup.bean.Student">
<!-- type属性要和构造器中设置参数的类型匹配(long,String,int,String)
     基于类型匹配构造器不能换位置 -->
   <constructor-arg type="long" value="11"></constructor-arg>
    <constructor-arg type="java.lang.String" value="tom1"></constructor-arg>
     <constructor-arg type="int" value="33"></constructor-arg>
      <constructor-arg type="java.lang.String" value="34@qq.com"></constructor-arg>
</bean>
<!-- 3.基于构造器中的变量名设置值 
     name指向构造器中的变量名-->
<bean name="stu2" class="com.briup.bean.Student">
  <constructor-arg name="id" value="33"></constructor-arg>
   <constructor-arg name="name" value="jake"></constructor-arg>
    <constructor-arg name="age" value="12"></constructor-arg>
     <constructor-arg name="email" value="by@qq.com"></constructor-arg>
</bean>
<!-- 上面三种结合 -->
<bean name="stu3" class="com.briup.bean.Student">
  <constructor-arg index="0" name="id"><value>11</value></constructor-arg>
  <constructor-arg index="1" name="name" ref="str"></constructor-arg>
  <constructor-arg index="2" name="age" value="34"></constructor-arg>
  <constructor-arg index="3" name="email">
    <!--<ref bean="str"/>-->
         <bean id="str" class="java.lang.String">
         <constructor-arg index="0" value="kks"></constructor-arg>
	 </bean> 
</constructor-arg>
</bean>
<bean id="str" class="java.lang.String">
  <constructor-arg index="0" value="kks"></constructor-arg>
</bean>
</beans>

测试类:

	@Test
	public void construct_test() {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext("com/briup/IOC/construct.xml");
		Student s=(Student) cp.getBean("stu2");
		System.out.println(s);
	}


3)自动装配 :容器依照一些规则去装配bean中的一个属性
      
在beans标签中配置装载方式:default-autowire="byName"
或者在bean标签中指定配置方式
a. autowire="byName":
spring容器会到当前的类中找property的名字,然后
再根据这个名字去spring容器中找有没有和这个property
名字相同的对象,有的话,就把这个对象当做参数放到
setXxxx这个方法里面注入进来.
注意:了解property指的类中的什么东西。

b,autowire="byType":
spring容器会根据当前类中的set方法里面参数的类型,
去容器中找相匹配的对象,如果没找到就算了,如果找到
一个就注入进来,如果找到多个,那么就会报错了.
c,autoWirde = "constructor" 根据构造器的参数类型去匹配
    如果所有属性(基本类型)
d,autoWire = "autoDetect" 自动检测
e.autowire = "default"

例子:
public class SomeBean {
 //自动装配
private String str2;
private OtherBean ob;
public SomeBean(OtherBean ob) {
super();
this.ob = ob;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
public OtherBean getOb() {
return ob;
}
public void setOb(OtherBean ob) {
this.ob = ob;
}
public void printInfo(){
System.out.println("str2 "+str2 +" ob "+ob);
}
}
public class OtherBean {
//自动装配
private String str1;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "str1 "+str1;
}  
}
配置文件的写法
<bean id="otherBean" class="ioc.OtherBean">
<property name="str1" value="String1" />
</bean>
<!-- <bean id="someBean" class="ioc.SomeBean" autowire="byName">
<property name="str2" value="String2" />
</bean>
 <bean id="someBean" class="ioc.SomeBean" autowire="byType">
<property name="str2" value="String2" />
</bean>
  <bean id="someBean" class="ioc.SomeBean" autowire="constructor">
<property name="str2" value="String2" />
</bean>
配置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.xsd"
          default-autowire="byName">  
          <!-- autowire自动匹配,自动转载
               byType基于类型匹配并转载,特点:基于set方法的参数类型匹配,使用byType时,必须保证该类型只能出现一次
               byName基于名字匹配,特点:基于set后首字母小写的名字和bean标签中的名字匹配
               default采用默认的,前提:和一级标签beans中的属性default-autowire结合使用
               default-autowire设置的是全局的匹配方式
               如果bean标签配置 类匹配对象的方式,一级标签配置的 default-autowire失效(就近原则)
               autowire="no" 不采用自动匹配 -->
     <!-- <bean name="us" class="com.briup.bean.UserService" autowire="byType">
     </bean> -->     
     <!-- <bean name="us" class="com.briup.bean.UserService" autowire="byName">
     </bean> -->
     <bean name="us" class="com.briup.bean.UserService" autowire="default">
     </bean>
     <bean name="dao1" class="com.briup.bean.UserDao">
     <property name="id" value="101"></property>
     </bean> 
     <bean name="dao" class="com.briup.bean.UserDao">
     <property name="id" value="100"></property>
     </bean>
     
     
     <!--autowire="constructor"基于构造器中的参数匹配,默认基于类型匹配,如果类型找到多个的时候,再基于名字匹配  -->
     <bean name="us1" class="com.briup.bean.UserService" autowire="constructor">
     <constructor-arg index="0" value="1"></constructor-arg>
      <constructor-arg index="1" value="tom"></constructor-arg>
     </bean>
</beans>

测试类:

@Test
	public void auto_test() {
		try {
			ClassPathXmlApplicationContext cp=
					new ClassPathXmlApplicationContext("com/briup/IOC/auto.xml");
			UserService ser=(UserService) cp.getBean("us");
			System.out.println(ser);
			System.out.println(ser.getDao());
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


注意:自动装配的优先级低于手动装配
自动装配一般用于快速开发建立系统原型的情况,但是在正式的开发中很少使用,
因为容易出错,难以维护;

4)继承装入: 并不是oo的继承关系
(bean的定义的继承,指bean的配置可去继承
                True 抽象化 客户端不能getBean了
  Abstract =  
                False 默认
Parent = "父类bean的id"

例子:
public class Car {
//bean的定义的继承
private String owner;
private String name;
private int price;
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return owner+" "+name+" "+price;
}
}
<bean id="abstractCar" class="ioc.Car" abstract="true">
<property name="owner" value="zwb" />
</bean>
<bean id="car1" parent="abstractCar">
<property name="name" value="qq" />
<property name="price" value="10" />
</bean>
<bean id="car2" parent="abstractCar">
<property name="name" value="baoma" />
<property name="price" value="70" />
</bean>
public class Test {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc6applicationContext.xml");
    Car car1=(Car) ac.getBean("car1");
    Car car2=(Car) ac.getBean("car2");
    System.out.println(car1.toString());
    System.out.println(car2.toString());
}
}
例:
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.xsd">
          <!-- abstract="ture"通知spring该bean不构建对象,
               模板,让其他标签继承用的 -->
<bean name="stu_pa" class="com.briup.bean.Student" abstract="true">
<property name="name" value="tom"></property>
<property name="age" value="30"></property>
<property name="email" value="12@qq.com"></property>
</bean>
<!-- parent="stu_pa"表示父标签或者模板是谁,继承模板中的所有配置(子标签) -->
<bean name="stu" class="com.briup.bean.Student" parent="stu_pa">
<property name="id" value="1"></property>
<!-- <property name="name" value="tom"></property>
<property name="age" value="30"></property>
<property name="email" value="12@qq.com"></property> -->
</bean>
<bean name="stu1" class="com.briup.bean.Student" parent="stu_pa">
<property name="id" value="2"></property>
<!-- <property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="email" value="12@qq.com"></property> -->
</bean>
<bean name="stu2" class="com.briup.bean.Student" parent="stu_pa">
<property name="id" value="3"></property>
<!-- <property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="email" value="12@qq.com"></property> -->
</bean>
</beans>


测试代码:

@Test
public void extends_test() {
	try {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext("com/briup/IOC/extends.xml");
			Student stu=(Student) cp.getBean("stu");
			Student stu1=(Student) cp.getBean("stu1");
			Student stu2=(Student) cp.getBean("stu2");
			System.out.println(stu);
			System.out.println(stu1);
			System.out.println(stu2);
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值