目录
Spring 管理 Bean-IOC--基于 XML 配置bean
Spring 配置/管理 bean 介绍
Bean 管理包括两方面
Bean 配置方式
基于 XML 配置 bean
通过 spring 的ioc 容器, 获取一个bean 对象
获取 bean 的方式:按类型
Monster类
注意
xml配置
细节说明
通过构造器配置 bean
xml配置
使用细节
通过 p 名称空间配置 bean
xml配置
引用/注入其它 bean 对象--ref
MemberDAOImpl
MemberServiceImpl
xml配置
引用/注入内部 bean 对象--内部 bean 对象
xml配置
引用/注入集合/数组类型
在 spring 的 ioc 容器, 看看如何给 bean
Master.java
配置 beans.xml
setCollectionByPro
通过 util 名称空间创建 list
创建BookStore 类
修改 beans.xml , 增加配置
级联属性赋值
创建Dept.java
创建Emp.java
修改 beans.xml
通过静态工厂获取对象
MyStaticFactory类
修改 beans.xml
通过实例工厂获取对象
MyInstanceFactory 类
修改 beans.xml
通过 FactoryBean 获取对象
创建 MyFactoryBean
配置beans.xml
bean 配置信息重用(继承)
配置beans.xml
bean 创建顺序
配置beans.xml
bean 对象的单例和多例
● 说明
创建car.java
配置beans.xml
使用细节
bean 的生命周期
● 说明:
创建House.java
配置beans.xml
使用细节
配置 bean 的后置处理器
说明
创建后置处理器MyBeanPostProcessor.java
配置beans.xml
其它说明
通过属性文件给 bean 注入值
src/ 创建 my.properties
配置beans.xml
基于 XML 的 bean 的自动装配
OrderDao
OrderService
OrderAction
配置beans.xml
spring eel 表达式
SpELBean.java
配置beans.xml
测试
创建 bean 对象
给 bean 注入属性
基于 xml 文件配置方式
基于注解方式
通过类型来获取 bean
public void getBeanByType() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
//,直接传入class对象/类型
Monster bean = ioc.getBean(Monster.class);
System.out.println("bean=" + bean);
}
无参构造器一定要写,Spring反射创建对象时,需要使用
public class Monster {
private Integer monsterId;
private String name;
private String skill;
//全参构造器
public Monster(Integer monsterId, String name, String skill) {
this.monsterId = monsterId;
this.name = name;
this.skill = skill;
}
//无参构造器一定要写,Spring反射创建对象时,需要使用
public Monster() {
}
public Integer getMonsterId() {
return monsterId;
}
public void setMonsterId(Integer monsterId) {
this.monsterId = monsterId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Monster{" +
"monsterId=" + monsterId +
", name='" + name + '\'' +
", skill='" + skill + '\'' +
'}';
}
}
1. 按类型来获取 bean, 要求 ioc 容器中的同一个类的 bean 只能有一个,
否则会抛出异常 NoUniqueBeanDefinitionException
2. 这种方式的应用场景:
比如 XxxAction/Servlet/Controller, 或 XxxService 在一个线程中只需要一个对象实例(单例)的情况
3. 这里在说明一下:
在容器配置文件(比如 beans.xml)中给属性赋值, 底层是通过setter 方法完成的, 这也是为什么我们需要提供 setter 方法的原因
public void setBeanByConstructor() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster monster03 = ioc.getBean("monster03", Monster.class);
System.out.println("monster03=" + monster03);
}
1. constructor-arg标签可以指定使用构造器的参数
2. index表示构造器的第几个参数 从0开始计算的
3. 除了可以通过index 还可以通过 name / type 来指定参数方式
4. 解除大家的疑惑, 类的构造器,不能有完全相同类型和顺序的构造器,所以可以通过type来指定
1. 通过 index 属性来区分是第几个参数
2. 通过 type 属性来区是什么类型(按照顺序)
//通过p名称空间来设置属性
@Test
public void setBeanByP() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster monster06 = ioc.getBean("monster06", Monster.class);
System.out.println("monster06=" + monster06);
}
//通过ref来设置bean属性
@Test
public void setBeanByRef() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService =
ioc.getBean("memberService", MemberServiceImpl.class);
memberService.add();
}
public class MemberDAOImpl {
//构造器...
public MemberDAOImpl() {
//System.out.println("MemberDAOImpl 构造器被执行...");
}
//方法
public void add() {
//System.out.println("MemberDAOImpl add()方法被执行");
}
}
public class MemberServiceImpl {
private MemberDAOImpl memberDAO;
public MemberServiceImpl() {
//System.out.println("MemberServiceImpl() 构造器被执行");
}
public MemberDAOImpl getMemberDAO() {
return memberDAO;
}
public void setMemberDAO(MemberDAOImpl memberDAO) {
//System.out.println("setMemberDAO()...");
this.memberDAO = memberDAO;
}
public void add() {
System.out.println("MemberServiceImpl add() 被调用..");
memberDAO.add();
}
}
1. 创建 MemberDAOImpl.java, 前面有了
2. 创建 MemberServiceImpl.java, 前面有
//通过内部bean设置属性
@Test
public void setBeanByPro() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService2 =
ioc.getBean("memberService2", MemberServiceImpl.class);
memberService2.add();
}
只需要修改一下xml配置就好
其中包括
list map set 数组 Properties
1. 创建 Monster.java, 前面有了
2. 创建Master.java
public class Master {
private String name;//主人名
private List monsterList;
private Map monsterMap;
private Set monsterSet;
//数组
private String[] monsterName;
//Java基础
//这个Properties 是 Hashtable的子类 , 是key-value的形式
//这里Properties key和value 都是String
private Properties pros;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getMonsterList() {
return monsterList;
}
public void setMonsterList(List monsterList) {
this.monsterList = monsterList;
}
public Map getMonsterMap() {
return monsterMap;
}
public void setMonsterMap(Map monsterMap) {
this.monsterMap = monsterMap;
}
public Set getMonsterSet() {
return monsterSet;
}
public void setMonsterSet(Set 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;
}
@Override
public String toString() {
return "Master{" +
"name='" + name + '\'' +
", monsterList=" + monsterList +
", monsterMap=" + monsterMap +
", monsterSet=" + monsterSet +
", monsterName=" + Arrays.toString(monsterName) +
", pros=" + pros +
'}';
}
}
给list属性赋值
给map属性赋值
给set属性赋值
给数组属性赋值
说一句: array标签中使用 value 还是 bean , ref .. 要根据你的业务决定
给Properties属性赋值 结构k(String)-v(String)
小妖怪
大妖怪
老妖怪
root
123456
127.0.0.1
- 获取 list 集合
- 获取 map 集合
- 获取 set
- 获取数组
- 获取 properties 集合
public void setCollectionByPro() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Master master01 = ioc.getBean("master01", Master.class);
//获取 list 集合
System.out.println("======list=======");
List monster_list = master01.getMonsterList();
for (Monster monster : monster_list) {
System.out.println(monster);
}
//获取 map 集合
System.out.println("======map=======");
Map monster_map = master01.getMonsterMap();
Set> entrySet = monster_map.entrySet();
for (Map.Entry entry : entrySet) {
System.out.println(entry);
}
//获取 set
System.out.println("======set=======");
Set monsterSet = master01.getMonsterSet();
for (Monster monster : monsterSet) {
System.out.println(monster);
}
//获取数组
System.out.println("======数组=======");
String[] monsterName = master01.getMonsterName();
for (String s : monsterName) {
System.out.println("妖怪名= " + s);
}
//获取 properties 集合
System.out.println("======properties=======");
Properties pros = master01.getPros();
String property1 = pros.getProperty("k1");
String property2 = pros.getProperty("k2");
String property3 = pros.getProperty("k3");
System.out.println(property1 + "\t" + property2 + "\t" + property3);
}
}
spring 的 ioc 容器, 通过 util 名称空间来创建 list 集合,可以当做创建 bean 对象的工具来
//使用util:list名称空间给属性赋值
@Test
public void setBeanByUtilList() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
BookStore bookStore = ioc.getBean("bookStore", BookStore.class);
System.out.println("bookStore=" + bookStore);
}
无参构造器,如果你没有其它的构造器,该无参构造器可以不写
但是如果你有其它的构造器,则必须显式的定义一下无参构造器
public class BookStore {
//书
private List bookList;
//无参构造器,如果你没有其它的构造器,该无参构造器可以不写
//但是如果你有其它的构造器,则必须显式的定义一下无参构造器
public BookStore() {
}
public List getBookList() {
return bookList;
}
public void setBookList(List bookList) {
this.bookList = bookList;
}
@Override
public String toString() {
return "BookStore{" +
"bookList=" + bookList +
'}';
}
}
如果没有自动导入则复制这二行 到上面
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
三国演义
红楼梦
西游记
水浒传
spring 的 ioc 容器, 可以直接给对象属性的属性赋值, 即级联属性赋值
//给属性进行级联赋值
@Test
public void setBeanByRelation() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Emp emp = ioc.getBean("emp", Emp.class);
System.out.println("emp=" + emp);
}
public class Dept {
private String name;
public Dept() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dept{" +
"name='" + name + '\'' +
'}';
}
}
public class Emp {
private String name;
private Dept dept;
public Emp() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"name='" + name + '\'' +
", dept=" + dept +
'}';
}
}
在 spring 的 ioc 容器, 可以通过静态工厂获对象
重新在获取一个bean因为他们所指定的工厂是静态的只会执行一次 所以他们是同一个对象
//通过静态工厂获取bean
//Java基础-静态和非静态
@Test
public void getBeanByStaticFactory() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster my_monster01 = ioc.getBean("my_monster01", Monster.class);
Monster my_monster04 = ioc.getBean("my_monster04", Monster.class);
System.out.println("my_monster01=" + my_monster01);
System.out.println(my_monster01 == my_monster04);//true
}
public class MyStaticFactory {
private static Map monsterMap;
//使用 static代码块 进行初始化
//在java基础的时候,讲过的
static {
monsterMap = new HashMap<>();
monsterMap.put("monster01", new Monster(100,"牛魔王","芭蕉扇"));
monsterMap.put("monster02", new Monster(200,"狐狸精","美人计"));
}
//提供一个方法,返回Monster对象
public static Monster getMonster(String key) {
return monsterMap.get(key);
}
}
在 spring 的 ioc 容器, 可以通过实例工厂获对象
重新在获取一个bean因为他们所指定的工厂是非静态的调用一次执行一次所以他们不是同一个对象
//通过实例工厂获取bean
@Test
public void getBeanByInstanceFactory() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster my_monster02 = ioc.getBean("my_monster02", Monster.class);
Monster my_monster03 = ioc.getBean("my_monster03", Monster.class);
System.out.println("my_monster02=" + my_monster02);
System.out.println("my_monster03=" + my_monster03);
System.out.println(my_monster02 == my_monster03);//false
}
public class MyInstanceFactory {
private Map monster_map;
//通过普通代码块进行初始化
{
monster_map = new HashMap<>();
monster_map.put("monster03", new Monster(300, "牛魔王~", "芭蕉扇~"));
monster_map.put("monster04", new Monster(400, "狐狸精~", "美人计~"));
}
//写一个方法返回Monster对象
public Monster getMonster(String key) {
return monster_map.get(key);
}
}
1. factory-bean 指定使用哪个实例工厂对象返回bean
2. factory-method 指定使用实例工厂对象的哪个方法返回bean
3. constructor-arg value="monster03" 指定获取到实例工厂中的哪个monster
在 spring 的 ioc 容器, 可以通过 FactoryBean 获取对象
//通过FactoryBean获取bean
@Test
public void getBeanByFactoryBean() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster my_monster05 = ioc.getBean("my_monster05", Monster.class);
System.out.println("my_monster05=" + my_monster05);
}
public class MyFactoryBean implements FactoryBean {
//这个就是你配置时候,指定要获取的对象对应key
private String key;
private Map 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;
}
@Override
public Monster getObject() throws Exception {
return monster_map.get(key);
}
@Override
public Class> getObjectType() {//得到类型
return Monster.class;
}
@Override
public boolean isSingleton() {//这里指定是否返是单例
return false;
}
}
在 spring 的 ioc 容器, 提供了一种继承的方式来实现 bean 配置信息的重用
//配置Bean通过继承
@Test
public void getBeanByExtends() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster monster11 = ioc.getBean("monster11", Monster.class);
System.out.println("monster11=" + monster11);
Monster monster13 = ioc.getBean("monster13", Monster.class);
System.out.println("monster13=" + monster13);
}
1. 配置Monster对象
2.但是这个对象的属性值和 id="monster10"对象属性一样
3.parent="monster10" 指定当前这个配置的对象的属性值从 id=monster10的对象来
在 spring 的 ioc 容器, 默认是按照配置的顺序创建bean 对象
//测试Bean创建顺序
@Test
public void testBeanByCreate() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
System.out.println("ok");
}
1. 在默认情况下, bean创建的顺序是按照配置顺序来的
2. 但是如果我们增加了 depends-on="department01" 这时就会先创建id= department01对象
配置Monster对象
1. 如果bean指定了 abstract="true", 表示该bean对象, 是用于被继承
2. 本身这个bean就不能被获取/实例化
在 spring 的 ioc 容器, 在默认是按照单例创建的,即配置一个 bean 对象后,ioc 容器只会
创建一个 bean 实例。如果,我们希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置
scope="prototype" 来指定
public class Car {
private Integer id;
private String name;
private Integer price;
public Car(Integer id, String name, Integer price) {
this.id = id;
this.name = name;
this.price = price;
}
public Car() {
}
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;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
1. 在默认情况下 scope属性是 singleton
2. 在ioc容器中, 只要有一个这个bean对象
3. 当程序员执行getBean时, 返回的的是同一个对象
4. 如果我们希望每次getBean返回一个新的Bean对象,则可以scope="prototype"
5. 如果bean的配置是 scope="singleton" lazy-init="true" 这时,ioc容器就不会提前创建该对象, 而是当执行getBean方法的时候,才会创建对象
@Test
public void testBeanScope() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Cat cat = ioc.getBean("cat", Cat.class);
Cat cat2 = ioc.getBean("cat", Cat.class);
Cat cat3 = ioc.getBean("cat", Cat.class);
System.out.println("cat=" + cat);
System.out.println("cat2=" + cat2);
System.out.println("cat3=" + cat3);
}
1. 默认是单例 scope=singleton,
在启动容器时, 默认就会创建 , 并放入到 singletonObjects 集合
2. 当
设置为多实例机制后, 该 bean 是在 getBean()时才创建
3. 如果是单例 scope=singleton,
同时希望在 getBean 时才创建 , 可以指定懒加载lazy init="true" (注意默认是 false)
4. 通常情况下,
lazy-init 就使用默认值 false , 在开发看来, 用空间换时间是值得的, 除非有特殊的要求.
5. 如果 scope="prototype"
这时你的 lazy-init 属性的值不管是 ture, 还是 false 都是在getBean 时候,才创建对象
bean 对象创建是由 JVM 完成的,然后执行如下方法
1. 执行构造器
2. 执行 set 相关方法
3. 调用 bean 的初始化的方法
4. 使用 bean
5. 当容器关闭时候,调用 bean 的销毁方法
1. 这里java基础
2. ioc的编译类型 ApplicationContext , 运行类型 ClassPathXmlApplicationContext
3. 因为ClassPathXmlApplicationContext 实现了 ConfigurableApplicationContext
4. ClassPathXmlApplicationContext 是有close
5. 将ioc 转成ClassPathXmlApplicationContext,再调用close
ioc.close();关闭ioc容器.
public void testBeanLife() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
House house = ioc.getBean("house", House.class);
System.out.println("使用house=" + house);
//关闭容器
//1. 这里又要考察大家的java基础
//2. ioc的编译类型 ApplicationContext , 运行类型 ClassPathXmlApplicationContext
//3. 因为ClassPathXmlApplicationContext 实现了 ConfigurableApplicationContext
//4. ClassPathXmlApplicationContext 是有close
//5. 将ioc 转成ClassPathXmlApplicationContext,再调用close
//ioc.close();
//关闭ioc容器.
((ConfigurableApplicationContext) ioc).close();
}
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()..");
}
@Override
public String toString() {
return "House{" +
"name='" + name + '\'' +
'}';
}
}
1. init-method="init" 指定bean的初始化方法 , 在setter方法后执行
2. init方法执行的时机,有spring容器来控制
3. destroy-method="destroy" 指定bean的销毁方法, 在容器关闭的时候执行
4. destroy方法执行的时机,有spring容器来控制
1. 初始化 init 方法和 destory 方法, 是程序员来指定
2. 销毁方法就是当关闭容器时,才会被调用
1. 在 spring 的 ioc 容器,可以配置 bean 的后置处理器
2. 该处理器/对象会在 bean 初始化方法调用前和初始化方法调用后被调用
3. 程序员可以在后置处理器中编写自己的代码
@Test
public void testBeanPostProcessor() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans02.xml");
House house = ioc.getBean("house", House.class);
System.out.println("使用house=" + house);
House house02 = ioc.getBean("house02", House.class);
System.out.println("使用house02=" + house02);
((ConfigurableApplicationContext)ioc).close();
}
创建 House.java 前面有
什么时候被调用: 在Bean的init方法前被调用
@param bean 传入的在IOC容器中创建/配置Bean
@param beanName 传入的在IOC容器中创建/配置Bean的id
@return Object 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
@throws BeansException
什么时候被调用: 在Bean的init方法后被调用
@param bean 传入的在IOC容器中创建/配置Bean
@param beanName 传入的在IOC容器中创建/配置Bean的id
@return 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
@throws BeansException
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 什么时候被调用: 在Bean的init方法前被调用
* @param bean 传入的在IOC容器中创建/配置Bean
* @param beanName 传入的在IOC容器中创建/配置Bean的id
* @return Object 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization().. bean="
+ bean + " beanName=" + beanName);
//初步体验案例: 如果类型是House的统一改成 上海豪宅
//对多个对象进行处理/编程==>切面编程
if(bean instanceof House) {
((House)bean).setName("上海豪宅~");
}
return null;
}
/**
* 什么时候被调用: 在Bean的init方法后被调用
* @param bean 传入的在IOC容器中创建/配置Bean
* @param beanName 传入的在IOC容器中创建/配置Bean的id
* @return 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization().. bean="
+ bean + " beanName=" + beanName);
return bean;
}
}
1. 当我们在 .xml 容器配置文件 配置了 MyBeanPostProcessor
2. 这时后置处理器对象,就会作用在该容器创建的Bean对象
3. 已经是针对所有对象编程->切面编程AOP
1、怎么执行到这个方法?=> 使用 AOP(反射+动态代理+IO+容器+注解)
2、有什么用?=> 可以对 IOC 容器中所有的对象进行统一处理 ,比如 日志处理/权限的校验/安全的验证/事务管理. - 初步体验: 如果类型是 House 的统一改成 上海豪宅
3、针对容器的所有对象吗? 是的=>切面编程特点
name=\u9EC4\u888D\u602A
id=10
skill=\u72EE\u5B50\u543C
@Test
public void setBeanByFile() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans03.xml");
Monster monster1000 = ioc.getBean("monster1000", Monster.class);
System.out.println("monster1000=" + monster1000);
}
1. 先把这个文件修改成提示All Problem
2. 提示错误,将光标放在context 输入alt+enter 就会自动引入namespace
3. location="classpath:my.properties" 表示指定属性文件的位置
4. 提示,需要带上 classpath
5. 属性文件有中文,需要将其转为unicode编码-> 使用工具
配置Monster对象
1.通过属性文件给monster对象的属性赋值
2. 这时我们的属性值通过${属性名}
3. 这里说的 属性名 就是 my.properties文件中的 k=v 的k
在 spring 的 ioc 容器,可以实现自动装配 bean
这里说的 Action 就是 Servlet->充当 Controller
public class OrderDao {
//方法。。。
public void saveOrder() {
System.out.println("保存 一个订单...");
}
}
public class OrderService {
//OrderDao属性
private OrderDao orderDao;
//getter
public OrderDao getOrderDao() {
return orderDao;
}
//setter
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
}
public class OrderAction {
//属性OrderService
private OrderService orderService;
//getter
public OrderService getOrderService() {
return orderService;
}
//setter
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
}
1. autowire="byType" 表示 在创建 orderService时通过类型的方式 给对象属性 自动完成赋值/引用
2. 比如OrderService 对象有 private OrderDao orderDao
3. 就会在容器中去找有没有 OrderDao类型对象
4. 如果有,就会自动的装配, 提示如果是按照 byType 方式来装配, 这个容器中,不能有两个 的OrderDao类型对象
5. 如果你的对象没有属性, autowire就没有必要写
6. 其它类推..7. 如果我们设置的是 autowire="byName" 表示通过名字完成自动装配
8. 比如下面的 autowire="byName" class="com.hspedu.spring.service.OrderService"
1) 先看 OrderService 属性 private OrderDao orderDao
2) 再根据这个属性的setXxx()方法的 xxx 来找对象id
3) public void setOrderDao() 就会找id=orderDao对象来进行自动装配
4) 如果没有就装配失败
1. Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象。
2. 和 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象
3. SpEL 使用#{…}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。
4. 不是重点,如果看到有人这样使用,能看懂即可
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;
}
@Override
public String toString() {
return "SpELBean{" +
"name='" + name + '\'' +
", monster=" + monster +
", monsterName='" + monsterName + '\'' +
", crySound='" + crySound + '\'' +
", bookName='" + bookName + '\'' +
", result=" + result +
'}';
}
}
通过spel给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);
}