※ 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();
}
}