Spring-IOC—基于XML配置Bean

1.Spring 配置/管理 bean 介绍

1.Bean 管理包括两方面

1.创建bean对象

2.给bean注入属性

2.Bean配置方式

1.基于xml文件配置方式

2.基于注解方式

2.基于XML配置bean

1.通过类型来获取bean

1.应用案例

<!--2.通过类型获取bean-->
<bean class="com.llp.spring.bean.Monster"><property name="monsterId" value="3"/><property name="name" value="琪琪"/><property name="skill" value="魅惑"/>
</bean>
    @Testpublic void getBeanByType(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");//通过类型获取bean,要求 ioc 容器中的同一个类的 bean 只能有一个!!Monster bean = ioc.getBean(Monster.class);System.out.println(bean);}

2.使用细节

1、按类型来获取 bean, 要求 ioc 容器中的同一个类的 bean 只能有一个, 否则会抛出异常

org.springframework.beans.NotWritablePropertyException: Invalid property ‘skill’ of bean class [com.llp.spring.bean.Monster]: Bean property ‘skill’ is not writable or has an invalid setter method.

2、这种方式的应用场景:比如 XxxAction/Servlet/Controller, 或 XxxService 在一个线程

3、在容器配置文件(比如 beans.xml)中给属性赋值, 底层是通过setter 方法完成的, 这也是为什么我们需要提供 setter 方法的原因

2.通过构造器配置bean

1.应用案例

beans.xml

    <!--3.通过构造器配置bean--><!--1. constructor-arg标签可以指定使用构造器的参数2. index表示构造器的第几个参数 从0开始计算的3. 除了可以通过index 还可以通过 name / type 来指定参数方式4. 类的构造器,不能有完全相同类型和顺序的构造器,所以可以通过type来指定--><!--index方式--><bean class="com.llp.spring.bean.Monster" id="monster03"><constructor-arg value="4" index="0"/><constructor-arg value="白骨精" index="1"/><constructor-arg value="吸血" index="2"/></bean><!--name方式--><bean class="com.llp.spring.bean.Monster" id="monster04"><constructor-arg value="5" name="monsterId"/><constructor-arg value="蜘蛛精" name="name"/><constructor-arg value="吸血" name="skill"/></bean><!--type方式--><!--为什么可以? 类的构造器,不能有完全相同类型和顺序的构造器,所以可以通过type来指定--><bean class="com.llp.spring.bean.Monster" id="monster05"><constructor-arg value="6" type="java.lang.Integer"/><constructor-arg value="黑熊精" type="java.lang.String"/><constructor-arg value="掏心" type="java.lang.String"/></bean>
    @Testpublic void getBeanByConstructor(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster monster03 = ioc.getBean("monster03",Monster.class);System.out.println(monster03);Monster monster04 = ioc.getBean("monster04",Monster.class);System.out.println(monster04);Monster monster05 = ioc.getBean("monster05",Monster.class);System.out.println(monster05);}

2.使用细节

  1. 通过 index 属性来区分是第几个参数
  2. 通过 type 属性来区分是什么类型(按照顺序)

3.通过p名称空间配置bean

1.应用案例

    <!--通过 p 名称空间配置 bean--><bean class="com.llp.spring.bean.Monster" id="monster06"p:monsterId="6"p:name="红孩儿"p:skill="三味真火"/>
    @Testpublic void getBeanByPNameSpace(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster bean = ioc.getBean("monster06",Monster.class);System.out.println(bean);}

4.引用/注入其他bean对象

1.应用案例

beans.xml

    <!--1. ref="memberDAO"表示  MemberServiceImpl对象属性memberDAO引用的对象是id=memberDAO的对象2. 这里就体现出spring容器的依赖注入3. 注意再spring容器中, 他是作为一个整体来执行的, 即如果你引用到一个bean对象, 对你配置的顺序没有要求4. 建议还是按顺序,好处是阅读的时候,比较方便--><bean class="com.llp.spring.service.MemberServiceImpl" id="memberService" p:memberDao-ref="memberDao"><!--<property name="memberDao" ref="memberDao"/>--></bean><!--引用/注入其他bean对象注意这里的memberDao和MemberServiceImpl配置中的ref一致--><bean class="com.llp.spring.dao.MemberDaoImpl" id="memberDao"/>
    //通过ref来设置bean属性@Testpublic void setBeanByRef(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");MemberServiceImpl memberService = ioc.getBean("memberService", MemberServiceImpl.class);memberService.add();}

5.引入/注入内部bean对象

1.应用案例

    <!--引用/注入其他bean对象--><bean class="com.llp.spring.dao.MemberDaoImpl" id="memberDao"/><!--配置MemberServiceImpl对象,使用内部bean的方式--><bean class="com.llp.spring.service.MemberServiceImpl" id="memberService2"><!--MemberServiceImpl对象中有一个属性memberDao,自己配置一个内部的bean--><property name="memberDao"><bean class="com.llp.spring.dao.MemberDaoImpl"/></property></bean>
    /*** 通过内部bean设置属性*/@Testpublic void setBeanByPro(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");MemberServiceImpl memberService = ioc.getBean("memberService2", MemberServiceImpl.class);memberService.add();}

6.引入/注入集合/数组类型

1.应用案例

Master.java实体类

public class Master {private String name;//主人名private List<Monster> monsterList;private Map<String, Monster> monsterMap;private Set<Monster> monsterSet;//数组private String[] monsterName;//Java基础//这个Properties 是 Hashtable的子类 , 是key-value的形式//这里Properties  key和value 都是Stringprivate Properties pros;public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Monster> getMonsterList() {return monsterList;}public void setMonsterList(List<Monster> monsterList) {this.monsterList = monsterList;}public Map<String, Monster> getMonsterMap() {return monsterMap;}public void setMonsterMap(Map<String, Monster> monsterMap) {this.monsterMap = monsterMap;}public Set<Monster> getMonsterSet() {return monsterSet;}public void setMonsterSet(Set<Monster> monsterSet) {this.monsterSet = monsterSet;}public String[] getMonsterName() {return monsterName;}public void setMonsterName(String[] monsterName) {this.monsterName = monsterName;}public Properties getPros() {return pros;}public void setPros(Properties pros) {this.pros = pros;}@Overridepublic String toString() {return "Master{" +"name='" + name + '\'' +", monsterList=" + monsterList +", monsterMap=" + monsterMap +", monsterSet=" + monsterSet +", monsterName=" + Arrays.toString(monsterName) +", pros=" + pros +'}';}
}
    <!--配置Master对象体会 spring 容器配置特点 依赖注入-非常灵活--><bean class="com.llp.spring.bean.Master" id="master"><property name="name" value="太上老君"/><!--给list属性赋值--><property name="monsterList"><list><!--引用的方法--><ref bean="monster01"/><ref bean="monster02"/><!--内部bean--><bean class="com.llp.spring.bean.Monster"><property name="name" value="老鼠精"/><property name="monsterId" value="100"/><property name="skill" value="吃粮食"/></bean></list></property><!--给map属性赋值--><property name="monsterMap"><map><entry><key><value>monster03</value></key><!--这里使用的外部bean,引入--><ref bean="monster03"/></entry><entry><key><value>monster04</value></key><ref bean="monster04"/></entry></map></property><!--给set属性赋值--><property name="monsterSet"><set><ref bean="monster05"/><ref bean="monster06"/><bean class="com.llp.spring.bean.Monster"><property name="name" value="金角大王"/><property name="skill" value="吐水"/><property name="monsterId" value="666"/></bean></set></property><!--给数组属性赋值array标签中使用 value 还是 bean , ref .. 要根据你的业务决定--><property name="monsterName"><array><value>小妖怪</value><value>大妖怪</value><value>老妖怪</value></array></property><!--给Properties属性赋值 结构k(String)-v(String)--><property name="pros"><props><prop key="username">root</prop><prop key="password">123456</prop><prop key="ip">127.0.0.1</prop></props></property></bean>

2.使用细节

  1. 主要掌握 List/Map/Properties 三种集合的使用.

  2. Properties 集合的特点

    1)这个 Properties 是 Hashtable 的子类 , 是 key-value 的形式

    2)key 是 string 而 value 也是 string

7.通过util名称空间创建list

1.应用案例

xmlns:util="http://www.springframework.org/schema/util"

beans.xml

  <util:list id="bookList"><value>三国演义</value><value>被讨厌的勇气</value><value>西游记</value><value>三字经</value></util:list><!--通过util名称空间创建list--><bean class="com.llp.spring.bean.BookStore" id="bookStore"><property name="bookList" ref="bookList"/></bean>

BookStore.java

public class BookStore {private List<String> bookList;public List<String> getBookList() {return bookList;}public void setBookList(List<String> bookList) {this.bookList = bookList;}@Overridepublic String toString() {return "BookStore{" +"bookList=" + bookList +'}';}
}

测试

 @Testpublic void getBeanByUtilList(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");BookStore bean = ioc.getBean("bookStore",BookStore.class);System.out.println(bean);}

8.级联属性赋值

1.应用案例

    <!--级联属性赋值--><bean class="com.llp.spring.bean.Emp" id="emp"><property name="name" value="小红"/><property name="dept" ref="dept"/><property name="dept.name" value="后勤"/></bean><bean class="com.llp.spring.bean.Dept" id="dept"/>
    /*** 级联属性赋值*/@Testpublic void getBeanByRelation(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Emp bean = ioc.getBean("emp", Emp.class);System.out.println(bean);}

9.通过静态工厂获取对象

1.应用案例

    <!--配置monster对象,通过静态工厂获取1. 通过静态工厂获取/配置bean2. class 是静态工厂类的全路径3. factory-method 表示是指定静态工厂类的哪个方法返回对象4. constructor-arg value="monster02" value是指定要返回静态工厂的哪个对象--><bean id="my_monster01" class="com.llp.spring.factory.MyStaticFactory" factory-method="getBean"><!--注意这里的value,通过value从map中获取monster对象       ==>MyStaticFactory.getBean(monsterMap.get(monster02))--><constructor-arg value="monster02"/></bean>

MyStaticFactory工厂类

/*** 可以创建返回Monster对象*/
public class MyStaticFactory {private static Map<String, Monster> monsterMap;//使用static 代码块进行初始化static{monsterMap = new HashMap<>();monsterMap.put("monster01",new Monster(100,"阿牛","芭蕉扇"));monsterMap.put("monster02",new Monster(200,"狐狸精","美人计"));}//提供一个方法返回monster对象public static Monster getBean(String key){return monsterMap.get(key);}}

测试类

    @Testpublic void getBeanByStaticFactory(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster bean = ioc.getBean("my_monster01", Monster.class);System.out.println(bean);}

测试结果

10.通过实例工厂获取对象

1.应用案例

beans.xml

<!--配置一个实例工厂对象-->
<bean class="com.llp.spring.factory.MyInstanceFactory" id="instanceFactory"/>
<!--配置monster对象,通过实例工厂1. factory-bean 指定使用哪个实例工厂对象返回bean2. factory-method 指定使用实例工厂对象的哪个方法返回bean3. constructor-arg value="monster03" 指定获取到实例工厂中的哪个monster
-->
<bean id="my_monster02" factory-bean="instanceFactory" factory-method="getMonster"><!--创建MyInstanceFactory工厂类1.MyInstanceFactory instanceFactory = new MyInstanceFactory();通过value传入getMonster中获取Monster对象2.instanceFactory.getMonster(monster_Map.get(monster03));--><constructor-arg value="monster03"/>
</bean>

实例工厂类

public class MyInstanceFactory {private static Map<String, Monster> monster_Map;{monster_Map = new HashMap<>();monster_Map.put("monster03",new Monster(300,"孙悟空","耍光棍"));monster_Map.put("monster04",new Monster(400,"蜘蛛精","盘丝"));}public Monster getMonster(String key){return monster_Map.get(key);}
}

测试类

    @Testpublic void getBeanByInstanceFactory(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster bean01 = ioc.getBean("my_monster02", Monster.class);Monster bean02 = ioc.getBean("my_monster02", Monster.class);System.out.println(bean01);/*** 这里调用my_monster02 都是调用已经创建好的MyInstanceFactory对象的getMonster方法* 注意的是,MyInstanceFactory是单独配置的并不会创建两次*/System.out.println(bean01 == bean02);//true }

测试结果

11.通过FactoryBean获取对象(重点)

1.应用案例

FactoryBean

/*** 一个FactoryBean*/
public class MyFactoryBean implements FactoryBean<Monster> {//这个就是你配置时候,指定要获取的对象对应keyprivate String key;private Map<String, Monster> monster_map;{   //代码块,完成初始化monster_map = new HashMap<>();monster_map.put("monster03", new Monster(300, "牛魔王~", "芭蕉扇~"));monster_map.put("monster04", new Monster(400, "狐狸精~", "美人计~"));}public void setKey(String key) {this.key = key;}@Overridepublic Monster getObject() throws Exception {return monster_map.get(key);}@Overridepublic Class<?> getObjectType() {return Monster.class;}@Overridepublic boolean isSingleton() {//这里指定是否返是单例return true;}
}

beans.xml

    <!--配置Monster对象,通过FactoryBean获取1. class 指定使用的FactoryBean2. key表示就是 MyFactoryBean 属性key3. value就是你要获取的对象对应key--><bean id="my_monster03" class="com.llp.spring.factory.MyFactoryBean"><!--MyFactoryBean myFactoryBean = new MyFactoryBean();myFactoryBean.setKey(monster_map.get(monster04))--><property name="key" value="monster04"/></bean>

测试类

@Test
public void getBeanByFactoryBean(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster my_monster03 = ioc.getBean("my_monster03", Monster.class);System.out.println(my_monster03);
}

测试结果

12.bean配置信息重用(继承)

1.应用案例

beans.xml

<!--配置Monster对象-->
<bean id="monster10" class="com.llp.spring.bean.Monster"><property name="monsterId" value="10"/><property name="name" value="蜈蚣精"/>
<property name="skill" value="蜇人"/></bean><!--
1.配置Monster对象
2.但是这个对象的属性值和id=monster10的对象属性一致
3.parent="monster10"表示指定当前配置对象的属性值从id=monster10的对象获取
-->
<bean id="monster11" class="com.llp.spring.bean.Monster" parent="monster10"/>

测试类

    /*** 配置bean通过继承(extends)*/@Testpublic void getBeanByExtends(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster monster10 = ioc.getBean("monster10", Monster.class);Monster monster11 = ioc.getBean("monster11", Monster.class);System.out.println(monster10);System.out.println(monster11);//monster11对象的属性值继承至monster10,但monster11和monster10并不是同一个对象System.out.println(monster10 == monster11);//false}

测试结果

注意

<!--配置Monster对象
1.如果bean指定了abstract="true",表示该对象适用于被继承的
2.这个bean本身是不能被实例化的
3.这个bean的价值就是专门用来被继承的
-->
<bean id="monster12" class="com.llp.spring.bean.Monster" abstract="true"><property name="monsterId" value="10"/><property name="name" value="蜈蚣精"/><property name="skill" value="蜇人"/>
</bean>

13.bean创建顺序

1.应用案例

beans.xml

    <!--测试bean对象的创建顺序1. 在默认情况下, bean创建的顺序是按照配置顺序来的(从上到下)2. 但是如果我们增加了 depends-on="department01" 这时就会先创建id= department01对象--><bean id="student01" class="com.llp.spring.bean.Student" depends-on="department01"/><bean id="department01" class="com.llp.spring.bean.Department"/>

测试类

    @Testpublic void getBeanByCreate(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Student student = ioc.getBean("student01", Student.class);Department department = ioc.getBean("department01", Department.class);}

测试结果

2.一个问题?

● 问题说明

  1. 先看下面的配置, 请问两个 bean 创建的顺序是什么? 并分析执行流程

​ 1)先创建 id=memberDAOImpl

​ 2)再创建 id = memberServiceImpl

​ 3)调用 memberServiceImpl.setMemberDAO() 完成引用

  1. 先看下面的配置, 请问两个 bean 创建的顺序是什么, 并分析执行流程

​ 1)先创建 id = memberServiceImpl

​ 2)再创建 id=memberDAOImpl

​ 3)用 memberServiceImpl.setMemberDAO() 完成引用

14.bean对象的单例和多例

1.应用案例

在 spring 的 ioc 容器, 在默认是按照单例创建的,即配置一个 bean 对象后,ioc 容器只会创建一个 bean 实例。

如果,我们希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置scope=“prototype” 来指定

Cat.java

public class Cat {private Integer id;private String name;public Cat() {System.out.println("Cat() 被执行...");}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}//@Override//public String toString() {//    return "Cat{" +//            "id=" + id +//            ", name='" + name + '\'' +//            '}';//}
}

beans.xml

 <!--配置Cat对象1. 在默认情况下 scope属性是 singleton2. 在ioc容器中, 只要有一个这个bean对象3. 当程序员执行getBean时, 返回的的是同一个对象4. 如果我们希望每次getBean返回一个新的Bean对象,则可以scope="prototype"5. 如果bean的配置是 scope="singleton" lazy-init="true" 这时,ioc容器就不会提前创建该对象, 而是当执行getBean方法的时候,才会创建对象
--><bean id="cat" class="com.llp.spring.bean.Cat" scope="prototype" lazy-init="false"><property name="id" value="100"/><property name="name" value="小花猫"/></bean>

测试

    @Testpublic void getBeanByPrototype(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Cat cat01 = ioc.getBean("cat", Cat.class);Cat cat02 = ioc.getBean("cat", Cat.class);System.out.println(cat01);System.out.println(cat02);//falseSystem.out.println(cat01==cat02);}

测试结果

2.使用细节

  1. 默认是单例singleton, 在启动容器时, 默认就会创建 , 并放入到singletonObjects集合

  2. 当 < bean scope=“prototype” > 设置为多实例机制后, 该 bean 是在 getBean()时才创建

  3. 如 果 是 单 例 singleton, 同 时 希 望 在 getBean 时 才 创 建 , 可 以 指 定 懒 加 载 lazy-init=“true” (注意默认是 false)

  4. 通常情况下, lazy-init 就使用默认值 false , 在开发看来, 用空间换时间是值得的, 除非有特殊的要求.

  5. 如果 scope=“prototype” 这时你的 lazy-init 属性的值不管是 ture, 还是 false 都是在getBean 时候才创建对象.

15.bean的生命周期

1.应用案例

● 说明: bean 对象创建是由 JVM 完成的,然后执行如下方法

  1. 执行构造器
  2. 执行 set 相关方法
  3. 调用 bean 的初始化的方法(需要配置)
  4. 使用 bean
  5. 当容器关闭时候,调用 bean 的销毁方法(需要配置)

House.java

public class House {private String name;public House() {System.out.println("House() 构造器...");}public String getName() {return name;}public void setName(String name) {System.out.println("House setName()=" + name);this.name = name;}//1. 这个方法是程序员来编写的.//2. 根据自己的业务逻辑来写.public void init() {System.out.println("House init()..");}//1. 这个方法是程序员来编写的.//2. 根据自己的业务逻辑来写.//3. 名字也不是固定的public void destroy() {System.out.println("House destroy()..");}@Overridepublic String toString() {return "House{" +"name='" + name + '\'' +'}';}
}

beans.xml

    <!--配置House对象,演示整个Bean的生命周期1. init-method="init" 指定bean的初始化方法 , 在setter方法后执行2. init方法执行的时机,有spring容器来控制3. destroy-method="destroy" 指定bean的销毁方法, 在容器关闭的时候执行4. destroy方法执行的时机,有spring容器来控制--><bean id="house" class="com.llp.spring.bean.House" init-method="init" destroy-method="destroy" ><property name="name" value="北京豪宅"/></bean>

测试

    //测试Bean的生命周期@Testpublic void testBeanLife() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");House house = ioc.getBean("house", House.class);System.out.println("使用house=" + house);//关闭容器//1. ioc的编译类型 ApplicationContext , 运行类型 ClassPathXmlApplicationContext//2. 因为ClassPathXmlApplicationContext 实现了 ConfigurableApplicationContext//3. ClassPathXmlApplicationContext 是有close//4. 将ioc 转成ClassPathXmlApplicationContext,再调用close//ioc.close();//关闭ioc容器.((ConfigurableApplicationContext) ioc).close();}

2.使用细节

  1. 初始化 init 方法和 destory 方法, 是程序员来指定

  2. 销毁方法就是当关闭容器时,才会被调用.

16.配置bean的后置处理器【比较难】

1.应用案例

● 说明

  1. 在 spring 的 ioc 容器,可以配置 bean 的后置处理器
  2. 该处理器/对象会在 bean 初始化方法调用前和初始化方法调用后被调用
  3. 程序员可以在后置处理器中编写自己的代码

● 应用实例演示

bean—House

public class House {private String name;public House() {System.out.println("House() 构造器...");}public String getName() {return name;}public void setName(String name) {System.out.println("House setName()=" + name);this.name = name;}//1. 这个方法是程序员来编写的.//2. 根据自己的业务逻辑来写.public void init() {System.out.println("House init()..");}//1. 这个方法是程序员来编写的.//2. 根据自己的业务逻辑来写.//3. 名字也不是固定的public void destroy() {System.out.println("House destroy()..");}@Overridepublic String toString() {return "House{" +"name='" + name + '\'' +'}';}
}

beans2.xml

 <!--配置house对象-->
<bean class="com.llp.spring.bean.House" id="house" init-method="init" destroy-method="destroy"><property name="name" value="我的房子"/>
</bean><!--配置后置处理器对象1. 当我们在beans02.xml 容器配置文件 配置了 MyBeanPostProcessor2. 这时后置处理器对象,就会作用在该容器创建的Bean对象3. 已经是针对所有对象编程->切面编程AOP-->
<bean class="com.llp.spring.bean.MyBeanPostProcessor"/>

后置处理器

/*** 后置处理器*/
public class MyBeanPostProcessor implements BeanPostProcessor {/*** 什么时候被调用:在Bean的init方法前被调用* @param bean 传入的在ioc容器中创建/配置的bean* @param beanName 传入的ioc容器中创建/配置bean的id* @return Object 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回* @throws BeansException*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessBeforeInitialization(),bean="+bean+",beanName="+beanName);return bean;}/*** 什么时候被调用:在Bean的init方法后被调用* @param bean 传入的在ioc容器中创建/配置的bean* @param beanName 传入的ioc容器中创建/配置bean的id* @return 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回* @throws BeansException*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization(),bean="+bean+",beanName="+beanName);return bean;}
}
@Test
public void testBeanPostProcessor(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans02.xml");House house = ioc.getBean("house", House.class);System.out.println(house);
}

2.其他说明

1、怎么执行到这个方法?=> 使用 AOP(反射+动态代理+IO+容器+注解)

2、有什么用?=> 可以对 IOC 容器中所有的对象进行统一处理 ,比如 日志处理/权限的校验

-初步体验案例: 如果类型是 House 的统一改成 上海豪宅

3、针对容器的所有对象吗? 是的=>切面编程特点

17.通过属性文件给 bean 注入值

1.应用实例

beans02.xml

<!--指定属性文件
location 表示指定属性文件的位置-->
<context:property-placeholder location="classpath:my.properties"/>
<!--配置Monster对象
1.通过属性文件给monster对象的属性赋值
2.这是我们的属性值通过${属性名}
3.这里说的属性名就是my.properties文件中的k=v的k-->
<bean class="com.llp.spring.bean.Monster" id="monster1000"><property name="monsterId" value="${monsterId}"/><property name="name" value="${name}"/><property name="skill" value="${skill}"/>
</bean>

测试

@Test
public void setBeanByFile(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans02.xml");Monster monster1000 = ioc.getBean("monster1000", Monster.class);//Monster{monsterId=100, name='琪琪', skill='魅惑'}System.out.println(monster1000);
}

18.基于XML的bean的自动装配

1.应用实例-byType

public class OrderDao {public void saveOrder(){System.out.println("保存 一个订单...");}
}
public class OrderServiceImpl {private OrderDao orderDao;public OrderDao getOrderDao() {return orderDao;}public void setOrderDao(OrderDao orderDao) {this.orderDao = orderDao;}public void saveOrder(){orderDao.saveOrder();}
}
public class OrderAction {private OrderServiceImpl orderService;public OrderServiceImpl getOrderService() {return orderService;}public void setOrderService(OrderServiceImpl orderService) {this.orderService = orderService;}public void saveOrder(){orderService.saveOrder();}
}
    <bean class="com.llp.spring.dao.OrderDao" id="orderDao"/><!--配置OrderService对象1. autowire="byType" 表示 在创建 orderService时通过类型的方式 给对象属性 自动完成赋值/引用2. 比如OrderService 对象有 private OrderDao orderDao3. 就会在容器中去找有没有 OrderDao类型对象4. 如果有,就会自动的装配, 如果是按照 byType 方式来装配, 这个容器中,不能有两个的OrderDao类型对象5. 如果你的对象没有属性,  autowire就没有必要写6. 其它类推..-->
<bean class="com.llp.spring.service.OrderServiceImpl" id="orderService" autowire="byType"/>
<bean class="com.llp.spring.web.OrderAction" id="orderAction" autowire="byType"/>

2.应用实例-byName

    <bean class="com.llp.spring.dao.OrderDao" id="orderDao"/><!--配置OrderService对象1. 如果我们设置的是 autowire="byName" 表示通过名字完成自动装配2. 比如下面的 autowire="byName" class="com.hspedu.spring.service.OrderService"1) 先看 OrderService 属性 private OrderDao orderDao2) 再根据这个属性的setXxx()方法的 xxx 来找对象id3) public void setOrderDao() 就会找id=orderDao对象来进行自动装配4) 如果没有就装配失败-->
<bean class="com.llp.spring.service.OrderServiceImpl" id="orderService" autowire="byName"/>
<bean class="com.llp.spring.web.OrderAction" id="orderAction" autowire="byName"/>
@Test
public void testAutowaireByName(){ApplicationContext ioc = new ClassPathXmlApplicationContext("beans03.xml");OrderAction orderAction = ioc.getBean("orderAction", OrderAction.class);System.out.println(orderAction.getOrderService());System.out.println(orderAction.getOrderService().getOrderDao());
}

19.Sping el表达式

1.应用实例

● 说明

  1. Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象。

  2. 和 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象

  3. SpEL 使用#{…}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。

public class SpELBean {private String name;private Monster monster;private String monsterName;private String crySound; //叫声private String bookName;private Double result;public SpELBean() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Monster getMonster() {return monster;}public void setMonster(Monster monster) {this.monster = monster;}public String getMonsterName() {return monsterName;}public void setMonsterName(String monsterName) {this.monsterName = monsterName;}public String getCrySound() {return crySound;}public void setCrySound(String crySound) {this.crySound = crySound;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public Double getResult() {return result;}public void setResult(Double result) {this.result = result;}//cry 方法会返回字符串public String cry(String sound) {return "发出 " + sound + "叫声...";}//read 返回字符串public static String read(String bookName) {return "正在看 " + bookName;}@Overridepublic String toString() {return "SpELBean{" +"name='" + name + '\'' +", monster=" + monster +", monsterName='" + monsterName + '\'' +", crySound='" + crySound + '\'' +", bookName='" + bookName + '\'' +", result=" + result +'}';}
}
<!--配置一个monster对象-->
<bean id="monster01" class="com.llp.spring.bean.Monster"><property name="monsterId" value="100"/><property name="name" value="蜈蚣精~"/><property name="skill" value="蜇人~"/>
</bean><!-- spring el 表达式使用1. 通过spel给bean的属性赋值-->
<bean id="spELBean" class="com.llp.spring.bean.SpELBean"><!-- sp el 给字面量 --><property name="name" value="#{'llp'}"/><!-- sp el 引用其它bean --><property name="monster" value="#{monster01}"/><!-- sp el 引用其它bean的属性值 --><property name="monsterName" value="#{monster01.name}"/><!-- sp el 调用普通方法(返回值)  赋值 --><property name="crySound" value="#{spELBean.cry('喵喵的..')}"/><!-- sp el 调用静态方法(返回值) 赋值 --><property name="bookName" value="#{T(com.llp.spring.bean.SpELBean).read('天龙八部')}"/><!-- sp el 通过运算赋值 --><property name="result" value="#{89*1.2}"/>
</bean>
//通过spring el 对属性赋值
@Test
public void setBeanBySpel() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans04.xml");SpELBean spELBean = ioc.getBean("spELBean", SpELBean.class);System.out.println("spELBean=" + spELBean);
}

测试结果

Spring-IOC—基于XML配置Bean相关推荐

  1. Spring IoC — 基于XML的配置

    1.属性注入 注意点: 1)如果类中显示定义了一个带参的构造函数,则一定还要显示提供一个无参构造函数,否则使用属性注入时将抛出异常. 2)JavaBean关于属性命名的特殊规范.Spring只会检查B ...

  2. Spring : spring基于xml配置Bean

    1.美图 2.案例 2.1 项目结构 2.2 user类 package com.spring.bean;import java.util.List;

  3. Spring学习--实现 FactoryBean 接口在 Spring IOC 容器中配置 Bean

    Spring 中有两种类型的 bean , 一种是普通的 bean , 另一种是工厂 bean , 即 FactroyBean. 工厂 bean 跟普通 bean 不同 , 其返回的对象不是指定类的一 ...

  4. Java学习笔记-Spring IoC 通过XML把Bean给IoC容器

    运行截图如下: 程序结构: 源码如下: Bean.java package springioc.demo.bean;public class Bean {public Bean(){System.ou ...

  5. Spring Ioc容器,基于xml的bean管理

    IOC容器 IOC思想基于IOC容器,IOC容器底层就是对象工厂 IOC底层 通过控制反转,使用xml配置文件和反射机制实现对对象的创建 IOC接口 实现IOC容器的两种方式 (1)BeanFacto ...

  6. spring框架的概述以及spring中基于XML的IOC配置——概念

    1.spring的概述     spring是什么     spring的两大核心     spring的发展历程和优势     spring体系结构 2.程序的耦合及解耦     曾经案例中问题   ...

  7. 实例化Bean的方法(基于xml配置)-http://blog.csdn.net/shymi1991/article/details/48153293

    实例化Bean的方法(基于xml配置) 标签: spring framework 2015-09-01 13:43 918人阅读 评论(0) 收藏 举报  分类: Spring FrameWork(7 ...

  8. spring中基于XML的AOP配置步骤

    spring中基于XML的AOP配置步骤 IAccountService.java package com.itheima.service;/*** 账户的业务层接口*/ public interfa ...

  9. Spring基础——在 Spring Config 文件中基于 XML 的 Bean 的自动装配

    一.Spring IOC 容器支持自动装配 Bean,所谓自动装配是指,不需要通过 <property> 或 <constructor-arg> 为 Bean 的属性注入值的过 ...

最新文章

  1. CentOS7.5(64位)安装Anaconda
  2. SAP库存历史库存表更新逻辑
  3. Hibernate工作原理
  4. java子类有参构造函数吗_为什么我需要在这个Java通用子类中有一个构造函数?...
  5. QML和C++混合编程--(一)
  6. vba 将html转换excel,利用VBA将不同格式excel模板之间进行数据转换实例
  7. windows 邮槽mailslot 在服务程序内建立后客户端无权限访问(GetLastError() == 5)的问题...
  8. Java笔记08-Map详解
  9. phpmyadmin4.8.1远程文件包含漏洞
  10. 使用logstash迁移es数据
  11. 微信小程序 设置微软雅黑字体
  12. 输入两个正整数,求其最大公约数和最小公倍数
  13. 网页加速器1.0.5.6 免费版
  14. const T 与T const的比较(const T vs.T const的翻译 Dan Saks)
  15. CLAHE算法代码详解
  16. 【python】python制作 连连看 游戏脚本(一)
  17. CPU卡的一个发卡详细过程
  18. java编写图书管理系统
  19. app卡在启动页面android,app启动一直停留在启动页面
  20. 局域网内的计算机拒绝访问,win10系统局域网拒绝访问的解决方法

热门文章

  1. 机器视觉照明技术Machine Vision Light Technique
  2. 关于在校专利软著申请一二事
  3. 智能语音时代,需要了解什么?
  4. stata:应用stata学习计量经济学原理 practice 6 边际效用 Marginal effect
  5. 「SequoiaDB巨杉数据库」Oma()概述2
  6. originos和鸿蒙系统的区别,originos是什么系统_originos和安卓有什么区别
  7. Google研究总监Peter Norvig:人工智能的另一面
  8. c语言 数组 随机数 初始化
  9. 熟男,好男,傻男,超男?-------…
  10. PHP扩展安装之PECL