栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring-IOC—基于XML配置Bean

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring-IOC—基于XML配置Bean

Spring-IOC—基于XML配置Bean 1.Spring 配置/管理 bean 介绍 1.Bean 管理包括两方面

1.创建bean对象

2.给bean注入属性

2.Bean配置方式

1.基于xml文件配置方式

2.基于注解方式

2.基于XML配置bean 1.通过类型来获取bean 1.应用案例


    
    
    

    @Test
    public 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

    
    
    
    
        
        
        
    

    
    
        
        
        
    

    
    
    
        
        
        
    
    @Test
    public 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.应用案例

    
    
    @Test
    public void getBeanByPNameSpace(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        Monster bean = ioc.getBean("monster06",Monster.class);
        System.out.println(bean);
    }
4.引用/注入其他bean对象 1.应用案例

beans.xml

    
    
        
    

    
    
    //通过ref来设置bean属性
    @Test
    public void setBeanByRef(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        MemberServiceImpl memberService = ioc.getBean("memberService", MemberServiceImpl.class);
        memberService.add();
    }

5.引入/注入内部bean对象 1.应用案例
    
    

    
    
        
        
            
        
    
    
    @Test
    public 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 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 +
                '}';
    }
}
    
    
        
        
        
            
                
                
                
                
                
                    
                    
                    
                
            
        
        
        
            
                
                    
                        monster03
                    
                    
                    
                
                
                    
                        monster04
                    
                    
                
            
        
        
        
            
                
                
                
                    
                    
                    
                
            
        
        
        
            
                小妖怪
                大妖怪
                老妖怪
            
        
        
        
            
                root
                123456
                127.0.0.1
            
        
    
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

  
        三国演义
        被讨厌的勇气
        西游记
        三字经
    
    
    
        
    

BookStore.java

public class BookStore {
    private List bookList;

    public List getBookList() {
        return bookList;
    }

    public void setBookList(List bookList) {
        this.bookList = bookList;
    }

    @Override
    public String toString() {
        return "BookStore{" +
                "bookList=" + bookList +
                '}';
    }
}

测试

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

8.级联属性赋值 1.应用案例
    
    
        
        
        
    
    
    
    @Test
    public void getBeanByRelation(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        Emp bean = ioc.getBean("emp", Emp.class);
        System.out.println(bean);
    }

9.通过静态工厂获取对象 1.应用案例
    
    
        
        
    

MyStaticFactory工厂类

public class MyStaticFactory {
    private static Map 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);
    }

}

测试类

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

测试结果

10.通过实例工厂获取对象 1.应用案例

beans.xml





    
    

实例工厂类

public class MyInstanceFactory {
    private static Map 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);
    }
}

测试类

    @Test
    public 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);
        
        System.out.println(bean01 == bean02);//true 
    }

测试结果

11.通过FactoryBean获取对象(重点) 1.应用案例

FactoryBean

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 true;
    }
}

beans.xml

    
    
        
        
    

测试类

@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



    
    




测试类

    
    @Test
    public 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
    }

测试结果

注意



    
    
    

13.bean创建顺序 1.应用案例

beans.xml

    
    
    

测试类

    @Test
    public 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

 
 
     
     
 

测试

    @Test
    public 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);
        //false
        System.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()..");
    }

    @Override
    public String toString() {
        return "House{" +
                "name='" + name + ''' +
                '}';
    }
}

beans.xml

    
    
        
    

测试

    //测试Bean的生命周期
    @Test
    public 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()..");
    }

    @Override
    public String toString() {
        return "House{" +
                "name='" + name + ''' +
                '}';
    }
}

beans2.xml

	

    


    

后置处理器

public class MyBeanPostProcessor implements BeanPostProcessor {

    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization(),bean="+bean+",beanName="+beanName);
        return bean;
    }

    
    @Override
    public 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



属性名}
3.这里说的属性名就是my.properties文件中的k=v的k-->

    
    
    

测试

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

    


2.应用实例-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;
    }

    @Override
    public String toString() {
        return "SpELBean{" +
                "name='" + name + ''' +
                ", monster=" + monster +
                ", monsterName='" + monsterName + ''' +
                ", crySound='" + crySound + ''' +
                ", bookName='" + bookName + ''' +
                ", result=" + result +
                '}';
    }
}


    
    
    




    
    
    
    
    
    
    
    
    
    
    
    

//通过spring el 对属性赋值
@Test
public void setBeanBySpel() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans04.xml");
    SpELBean spELBean = ioc.getBean("spELBean", SpELBean.class);
    System.out.println("spELBean=" + spELBean);
}

测试结果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/885028.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号