Spring系列二:基于XML配置bean 中

在这里插入图片描述

💖使用utillist进行配置

spring的ioc容器, 可以通过util名称空间来创建list集合

1.新建com.zzw.spring.bean.BookStore

public class BookStore {
    //书
    private List<String> bookList;

    //无参构造器, 如果没有其它的构造器, 该无参构造器可以不写
    //如果有其它的构造器, 则必须显示地定义一下无参构造器
    public BookStore() {
    }

	//getter, setter方法
}

2.src/beans.xml增加如下配置

<!--定义一个util:list, 并且指定了id 可以达到数据复用
说明: 在使用util:list 名称空间的时候, 需要引入相应的标签, 一般来说通过alt+enter会自动加入
, 如果没有就手动添加一下
-->
<util:list id="myBookList">
    <value>三体</value>
    <value>时间简史</value>
    <value>梦的解析</value>
    <value>福尔摩斯探案集</value>
</util:list>

<!--配置BookStore对象-->
<bean class="com.zzw.spring.bean.BookStore" id="bookStore">
    <property name="bookList" ref="myBookList"/>
</bean>

3.测试: com/zzw/spring/test/SpringBeanTest.java新增setBeanByUtilList方法

public class SpringBeanTest {
	//使用util:list名称空间给属性赋值
    @Test
    public void setBeanByUtilList() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        BookStore bookStore = ioc.getBean("bookStore", BookStore.class);
        System.out.println("bookStore=" + bookStore);
    }
}

💖属性级联赋值配置

spring的ioc容器, 可以直接给对象属性的属性赋值, 即级联属性赋值

1.新增com.zzw.spring.bean.Dept部门类

public class Dept {
    private String name;

    public Dept() {
    }

	//getter, setter方法

2.新建com.zzw.spring.bean.Employee员工类

public class Employee {
    private String name;
    private Dept dept;

    public Employee() {
    }
	
	//getter, setter方法
}

3.src/beans.xml增加如下配置

<!--配置Dept对象-->
<bean class="com.zzw.spring.bean.Dept" id="dept"/>
<!--配置Employee对象-->
<bean class="com.zzw.spring.bean.Employee" id="employee">
    <property name="name" value="tom"/>
    <property name="dept" ref="dept"/>
    <!--这里我希望给dept的name属性指定值[级联属性赋值]-->
    <property name="dept.name" value="java开发"/>
</bean>

4.测试: com/zzw/spring/test/SpringBeanTest.java新增setBeanByRelation方法

public class SpringBeanTest {
	//给属性进行级联赋值
    @Test
    public void setBeanByRelation() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        Employee employee = ioc.getBean("employee", Employee.class);
        System.out.println("employee=" + employee);
    }
}

💖通过静态工厂获取bean

在spring的ioc容器, 可以通过静态工厂获取bean对象

1.新建com.zzw.spring.factory.MyStaticFactory
这是一个静态工厂类-可以返回Monster对象

package com.zzw.spring.factory;

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

2.src/beans.xml增加如下配置

<!--配置Monster对象, 通过静态工厂获取
解读
1.通过静态工厂获取bean
2.class 是静态工厂类的全路径
3.factory-method 表示是指定静态工厂类的哪个方法返回对象
4.constructor-arg value="monster02" value是指定要返回静态工厂的哪一个对象
-->
<bean class="com.zzw.spring.factory.MyStaticFactory" id="myMonster01"
      factory-method="getMonster">
    <constructor-arg value="monster02"/>
</bean>

3.测试: com/zzw/spring/test/SpringBeanTest.java新增getBeanByStaticFactory方法

public class SpringBeanTest {
	//通过静态工厂获取bean
    @Test
    public void getBeanByStaticFactory() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        Monster myMonster01 = ioc.getBean("myMonster01", Monster.class);
        Monster myMonster02 = ioc.getBean("myMonster01", Monster.class);
        System.out.println("myMonster01=" + myMonster01);
        System.out.println(myMonster01 == myMonster02);//true. myMonster01和myMonster02是同一个对象
    }
}

💖bean配置信息重用

在spring的ioc容器, 提供了一种继承的方式来实现bean配置信息的重用

1.src/beans.xml增加如下配置

<!--配置Monster对象-->
<bean class="com.zzw.spring.bean.Monster" id="monster10"
      p:monsterId="10"
      p:name="蜘蛛侠"
      p:skill="吐丝"
/>
<!--
    1.配置Monster对象,
    2.但是这个对象的属性值和id="monster10"对象的属性值一样
    3.parent="monster10" 指定当前这个配置的对象的属性值从 id="monster10"的对象来
-->
<bean class="com.zzw.spring.bean.Monster" id="monster11" parent="monster10"/>


<!--配置Monster对象
1.如果bean指定了 abstract=true, 表示该bean对象, 是用于被继承
2.本身这个bean就不能被获取/实例化
-->
<bean class="com.zzw.spring.bean.Monster" id="monster12" abstract="true"
      p:monsterId="12"
      p:name="蜘蛛侠~"
      p:skill="吐丝~"
/>
<bean id="monster13" class="com.zzw.spring.bean.Monster" parent="monster12"/>

2.测试: com/zzw/spring/test/SpringBeanTest.java新增getBeanByExtends方法

public class SpringBeanTest {
	//通过继承, 配置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);
    }
}

💖bean创建顺序

在spring的ioc容器, 默认是按照配置的顺序创建bean对象

测试bean创建顺序

实验1
1.src/beans.xml增加如下配置

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

2.测试: com/zzw/spring/test/SpringBeanTest.java新增testBeanCreateOrder方法

public class SpringBeanTest {
    @Test
    public void testBeanCreateOrder() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

        System.out.println("ok~");
    }
}

3.新增com.zzw.spring.bean.Department

public class Department {
    public Department() {
        System.out.println("Department构造器 被执行");
    }
}

4.新增com.zzw.spring.bean.Student

public class Student {
    public Student() {
        System.out.println("Student构造器 被执行");
    }
}

提示: 会先创建student01这个bean对象, 然后创建department01这个bean对象

5.运行结果

Student构造器 被执行
Department构造器 被执行
ok~

如果这样配置, 会先创建department01对象, 再创建student01对象

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

6.运行结果

Department构造器 被执行
Student构造器 被执行
ok~

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

<!--配置MemberDaoImpl对象-->
<bean class="com.zzw.spring.dao.MemberDaoImpl" id="memberDao"/>

<bean class="com.zzw.spring.service.MemberServiceImpl" id="memberService">
    <property name="memberDao" ref="memberDao"/>
</bean>

2.答案:

  1. 先创建 id=memberDao
  2. 再创建 id=memberService
  3. 调用 memberService.setMemberDao() 完成引用

3.测试: com/zzw/spring/test/SpringBeanTest.javatestBeanCreateOrder方法

public class SpringBeanTest {
    @Test
    public void testBeanCreateOrder() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

        System.out.println("ok~");
    }
}

4.运行结果:

MemberDaoImpl 构造器...
MemberServiceImpl 构造器被执行
setMemberDao()...

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

<bean class="com.zzw.spring.service.MemberServiceImpl" id="memberService">
    <property name="memberDao" ref="memberDao"/>
</bean>

<!--配置MemberDaoImpl对象-->
<bean class="com.zzw.spring.dao.MemberDaoImpl" id="memberDao"/>

2答案:

  1. 先创建 id=memberService
  2. 再创建 id=memberDao
  3. 调用 memberService.setMemberDao() 完成引用

3.测试: com/zzw/spring/test/SpringBeanTest.javatestBeanCreateOrder方法

public class SpringBeanTest {
    @Test
    public void testBeanCreateOrder() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

        System.out.println("ok~");
    }
}

4.运行结果

MemberServiceImpl 构造器被执行
MemberDaoImpl 构造器...
setMemberDao()...

💖bean的单例和多实例

在spring的ioc容器中, 默认情况下是按照单例创建的. 即配置一个bean对象后, ioc容器只会创建一个bean对象
如果我们希望ioc容器配置的某个bean对象, 是以多个实例形式创建的. 则可以通过配置 scope=“prototype” 来指定

1.新建com.zzw.spring.bean.Cat

public class Cat {
    private Integer id;
    private String name;
    
    public Cat() {
    //getter, setter方法
}

2.src/beans.xml增加如下配置

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

3.测试: com/zzw/spring/test/SpringBeanTest.java增加testBeanScope方法

//测试Scope
@Test
public void testBeanScope() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
    Cat cat1 = ioc.getBean("cat", Cat.class);
    Cat cat2 = ioc.getBean("cat", Cat.class);
    Cat cat3 = ioc.getBean("cat", Cat.class);
    System.out.println("cat1=" + cat1);
    System.out.println("cat2=" + cat2);
    System.out.println("cat3=" + cat3);
}

使用细节
1)bean默认是单例singleton; 在启动容器时, bean默认就会创建, 并放入到singletonObjects
2) 当<bean scope="prototype">设置为多实例机制后, 该bean是在getBean()时被创建
3) 如果是单例singleton, 同时希望在getBean时才创建, 可以指定懒加载 lazy-init="true"(注意默认是false)
4) 通常情况下, lazy-init 就使用默认值false. 在开发看来, 空间换时间是值得的, 除非有特殊要求
5) 如果scope="prototype", 这时你的lazy-init 属性的值不管是true还是false, 都是在getBean的时候才创建这个对象

💖bean的生命周期

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

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

●代码实现
1.新建com.zzw.spring.bean.House

public class House {
    private String name;

    public House() {
        System.out.println("House构造器 被执行...");
    }

    public void setName(String name) {
        System.out.println("House setName()=" + name);
        this.name = name;
    }

    //解读
    //1.这个方法是由程序员来编写的
    //2.根据自己的业务逻辑来写.
    //3.名字也不是固定的
    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 + '\'' +
                '}';
    }
}

2.配置src/beans.xml

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

3.测试bean的生命周期com.zzw.spring.test.SpringBeanTest

public class SpringBeanTest {
    @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()
        //5.关闭ioc容器
        ((ClassPathXmlApplicationContext) ioc).close();
    }
}

4.输出

House构造器 被执行...
House setName()=上海豪宅
House init()....
setMemberDao()...
house=com.zzw.spring.bean.House@327bcebd
House destroy()...

使用细节
1.初始化-init方法和destroy方法, 由程序员来指定
2.销毁方法就是当关闭容器时, 才会被调用

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Spring,我们可以使用注解配置和装配Bean,这可以使我们的代码更加简洁和易于维护。下面是关于如何基于注解配置和装配Bean的一些简要介绍: 1. 基于注解配置Bean 在Spring,我们可以使用以下注解配置Bean: - @Component:表示该类是一个Spring Bean,需要被Spring容器管理。 - @Service:表示该类是一个服务层的Bean。 - @Controller:表示该类是一个控制层的Bean。 - @Repository:表示该类是一个数据访问层的Bean。 这些注解都是基于@Component注解的衍生注解,它们的作用是更加明确地表示Bean的角色。我们可以在Bean类上添加这些注解,告诉Spring容器该类需要被管理。例如: ``` @Service public class UserService { // ... } ``` 2. 基于注解装配Bean 在Spring,我们可以使用以下注解来装配Bean: - @Autowired:自动装配Bean。 - @Qualifier:指定具体的Bean名称进行装配。 - @Resource:指定具体的Bean名称进行装配,与@Qualifier类似。 - @Value:注入一个具体的值。 使用@Autowired注解进行自动装配时,Spring会自动在容器寻找与该类型匹配的Bean,并将其注入到类的属性。例如: ``` @Service public class UserService { @Autowired private UserDao userDao; // ... } ``` 使用@Qualifier或@Resource注解可以指定具体的Bean名称进行装配。例如: ``` @Service public class UserService { @Autowired @Qualifier("userDaoImpl") private UserDao userDao; // ... } ``` 使用@Value注解可以注入一个具体的值。例如: ``` @Service public class UserService { @Value("10") private int maxCount; // ... } ``` 以上就是关于Spring基于注解配置和装配Bean的简要介绍,希望能对您有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~ 小团子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值