Spring学习-IOC操作Bean管理(基于xml)

IOC容器

概念和原理

1、什么是IOC
- 控制反转,把对象的创建和对象之间的调用过程,交给Spring进行管理
- 使用IOC的目的:为了耦合度降低
- 入门案例是IOC的实现
2、IOC底层实现原理
- xml解析、工厂模式、反射
3、画图讲解IOC底层原理
在这里插入图片描述

在这里插入图片描述

4、IOC思想是基于IOC容器完成,IOC容器底层就是对象工厂

IOC接口

1、Spring提供了IOC容器实现的两种方式(两个接口):
- BeanFactory:IOC容器最基本实现的,是Spirng里面内部使用的接口,一般不提供开发 人员使用,特点是加载配置文件时不会创建里面的对象,在获取对象时才创建对象(懒汉式)
- ApplicationContext:BeanFactory的子接口,提供了更多更加强大的接口,一般由 开发人员进行使用。在加载配置文件就会把在配置文件对象进行创建(饿汉式)
2、ApplicationContext接口有实现类:
在这里插入图片描述

IOC操作Bean管理(概念)

1、什么时Bean管理

- Bean管理指的两个操作
- Spring创建对象
- Spring注入属性

2、Bean管理的操作有两种实现方式
- 基于xml配置文件方式实现
- 基于注解方式实现

IOC操作Bean管理(基于xml方式)

1、基于xml方式创建对象

 <bean id="user" class="com.sunrise.spring5.User"></bean>
- 在spring配置文件中,使用bean标签,标签里卖弄添加对应的属性,就可以实现对象的创建。
- id属性:唯一标识
- class属性:类全路径(包类属性)
- 创建对象时,默认执行无参构造方法完成对象的创建。

2、基于xml方式注入属性
- DI:依赖注入,就是注入属性
1. 使用使用set方法注入

		public class Book {
    private String bname;
    private String bouthor;

    public void setBname(String bname) {
        this.bname = bname;
    }

    public void setBouthor(String bouthor) {
        this.bouthor = bouthor;
    }
}
2. 使用有参数的构造注入:spring配置中property作为bean的属性。也就是指一个类中的成员。同时这个成员必须有get和set方法。
    <bean id = "book" class="com.sunrise.spring5.Book">
        <!--使用priperty完成属性注入-->
        <property name="bname" value="三体"></property>
        <property name="bouthor" value="刘慈欣"></property>
    </bean>

3、第二种注入方法:使用有参构造进行注入
- 创建类,定义属性,创建属性对应有参数构造方法

public class Order {
    private String oname;
    private String oaddress;

    public void setOname(String oname) {
        this.oname = oname;
    }

    public void setOaddress(String oaddress) {
        this.oaddress = oaddress;
    }

    public Order(String oname, String oaddress) {
        this.oname = oname;
        this.oaddress = oaddress;
    }
    public void show(){
        System.out.println("订单名:"+oname + "\n地址:"+ oaddress);
    }
}
- 在 spring 配置文件中进行配置
    <bean id="order" class="com.sunrise.spring5.Order">
        <constructor-arg name="oaddress" value="China"></constructor-arg>
        <constructor-arg name="oname" value="电脑"></constructor-arg>
    </bean>

4、P名称空间注入

  • 使用p名称空间注入,可以简化xml配置方式
    a 添加p名称空间在配置文件中
	<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
b 进行属性注入,在bean标签里面进行操作
	<bean id="book" class="com.sunrise.spring5.Book" p:bname="斗罗大陆" 	p:bauthor="唐家三少"></bean>

IOC操作Bean管理(xml注入其他类型属性)

1、字面量
- 注入null值

        <property name="address">
            <null/>
        </property>
- 属性值包含特殊符号
        <property name="address">
            <null/>
        </property>

2、注入属性-外部Bean
- 创建两个类service类和dao类
- 在service调用dao里面的方法
- 在spring配置文件中进行配置

public class UserService {
    //创建UserDao类型属性,生产set方法
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add(){
        System.out.println("service add.....");
        userDao.update();
        //创建UserDao对象
//        UserDao userDao = new UserDaoImpl();
    }
}
<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    service和dao对象创建-->
    <bean id = "userService" class="com.sunrise.spring5.service.UserService">
<!--        注入userDao对象
            name属性值:类里面的属性名称
            ref属性:创建userDao对象bean标签的id值-->
        <property name="userDao" ref="userDao" ></property>
    </bean>
    <bean id="userDao" class="com.sunrise.spring5.dao.UserDaoImpl"></bean>
</beans>

3、注入属性-内部bean
- 一对多关系:部门与员工,一个部门里面可以有多个员工,一个员工属于一个部门,部门是一,员工是多。
- 在实体类中表示他们的关系

public class Dept {
    private String dname;

    public void setDname(String dname) {
        this.dname = dname;
    }
}

public class Emp {
    private String ename;
    private String gender;
    //员工属于某一个部门
    private Dept dept;

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}
- 在spring完成配置文件
<?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 id="emp" class="com.sunrise.spring5.Bean.Emp">
        <property name="ename" value="jack" ></property>
        <property name="gender" value=""></property>
        <property name="dept" >
            <bean id="dept" class="com.sunrise.spring5.Bean.Dept">
                <property name="dname" value="IT部"></property>
            </bean>
        </property>
    </bean>
</beans>

4、注入属性的级联赋值
- 第一种写法

<?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 id="emp" class="com.sunrise.spring5.Bean.Emp">
        <property name="ename" value="jack" ></property>
        <property name="gender" value=""></property>

<!--        级联赋值-->
        <property name="dept" ref="dept"></property>
    </bean>

    <bean id="dept" class="com.sunrise.spring5.Bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>
</beans>
- 第二种写法
在Dept类中生成getDept()方法
    public Dept getDept() {
        return dept;
    }
<?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 id="emp" class="com.sunrise.spring5.Bean.Emp">
        <property name="ename" value="jack" ></property>
        <property name="gender" value=""></property>

<!--        级联赋值-->
        <property name="dept" ref="dept"></property>
        <property name="dept.dname" value="技术部"></property>
    </bean>

    <bean id="dept" class="com.sunrise.spring5.Bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>
</beans>

IOC操作bean管理(xml注入集合属性)

1、注入数组类型属性
2、注入List集合类型属性
3、注入Map集合类型属性
- 生成包含集合的类

public class Stu {
    //数组类型的属性
    private String[] courses;
    //创建list集合
    private List<String> lists;
    private Map<String, String> maps;
    public void setCourses(String[] courses) {
        this.courses = courses;
    }
    public void setLists(List<String> lists) {
        this.lists = lists;
    }

    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }
}
- 在spring配置文件中进行配置
<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--集合类型属性的注入-->
    <bean id="stu" class="com.sunrise.spring5.collectionType.Stu">
<!--        属性注入-->
        <property name="courses" >
            <array >
                <value >JAVA课程</value>
                <value >数据库课程</value>
            </array>
        </property>

        <property name="lists">
            <list >
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>
        <property name="maps">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry key="PHP" value="php"></entry>
            </map>
        </property>
    </bean>
</beans>

4、在集合里面设置对象类型值

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--集合类型属性的注入-->
    <bean id="stu" class="com.sunrise.spring5.collectionType.Stu">
<!--        属性注入-->
        <property name="courses" >
            <array >
                <value >JAVA课程</value>
                <value >数据库课程</value>
            </array>
        </property>

        <property name="lists">
            <list >
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>
        <property name="maps">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry key="PHP" value="php"></entry>
            </map>
        </property>
        <property name="courses1">
            <list>
               <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
    </bean>
    <bean name="course1" class="com.sunrise.spring5.collectionType.Course">
        <property name="cname" value="Spring5框架"></property>
    </bean>
    <bean name="course2" class="com.sunrise.spring5.collectionType.Course">
        <property name="cname" value="MyBatis框架"></property>
    </bean>
</beans>

5、把集合注入部分提取出来
- 在Spring配置文件中引入名称空间util

<?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:p="http://www.springframework.org/schema/p"
       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">
<!--集合类型属性的注入-->
- 使用util标签完成list集合属性注入
    <util:list id="booklist">
        <value>傲世丹神</value>
        <value>太容易坏</value>
        <value>三体</value>
    </util:list>
    <bean id="book" class="com.sunrise.spring5.collectionType.Book">
        <property name="list" ref="booklist"></property>
    </bean>

IOC操作Bean管理(FactoryBean)

1、Spring有两种类型的Bean,一种普通的bean,另外有一种工厂bean(FactoryBean)
2、普通的Bean:在配置文件中定义的Bean类型就是返回类型
3、工厂bean:在配置文件中定义的bean类型可以和返回的类型不一致
第一步 创建一个类,让此类作为工厂bean。实现接口FactoryBean
第二步 实现接口里面的方法

public class MyBean implements FactoryBean<Course> {
    //定义返回bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("sd");
        return course;
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() {
        return false;
    }
}

    @Test
    public void test3(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }

IOC操作Bean管理(Bean的作用域和生命周期)

1、在Spring里面可以设置创建的bean实例时单实例还是多实例
2、在Spring,默认情况下创建的bean实例是单实例对象

    public void test2(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book1 = context.getBean("book", Book.class);
        Book book2 = context.getBean("book", Book.class);
        System.out.println(book1);
        System.out.println(book2);

    }
com.sunrise.spring5.collectionType.Book@5c18298f
com.sunrise.spring5.collectionType.Book@5c18298f

3、如何设置单实例还是多实例
1 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例对象
2 scope属性值
- 默认值:singleton 表示单实例对象
- prottotype表示多实例对象

    <bean id="book" class="com.sunrise.spring5.collectionType.Book" scope="prototype">
        <property name="list" ref="booklist"></property>
    </bean>
com.sunrise.spring5.collectionType.Book@5c18298f
com.sunrise.spring5.collectionType.Book@31f924f5
	如上打印的地址值不同。
	- singleton和prototype区别:singleton表示单实例,prototype表示多实例。设置scope值时singleton时候,在加载配置文件时就会创建单实例对象。设置为scope为prototype,不是在加载spring配置文件时就创建对象,而是在调用getBean方法时创建多实例对象。
3 request属性:表示一次请求
4 session:表示一次会话

IOC操作Bean管理(Bean的生命周期)

1、生命周期
从对象创建到对象销毁的过程。
2、bean的生命周期
a 通过构造器创建bean实例(无参数构造)
b 为bean的属性设置值和对其他bean的引用(调用类中的set方法)
c 调用bean的初始化方法(需要进行配置)
d bean可以使用了(对象获取到了)
e 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
3、演示bean的生命周期

public class Orders {
    private String oname;

    //五参数的构造

    public Orders() {
        System.out.println("第一步执行无参数的构造创建bean实例");
    }

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二部 调用set方法设置值");
    }

    //创建执行的初始化方法
    public void initMethod(){
        System.out.println("第三步 执行初始化方法");
    }

    //创建销毁执行的方法
    public void destoryMethod(){
        System.out.println("第五步 执行销毁方法");
    }
}

  @Test
    public void test4(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步, 获取创建bean实例的对象");
        System.out.println(orders);

        //手动让bean实例销毁
        ((ClassPathXmlApplicationContext)context).close();
    }
    <bean id="orders" class="com.sunrise.spring5.bean.Orders" init-method="initMethod" destroy-method="destoryMethod">
        <property name="oname" value="手机"></property>
    </bean>

4、bean的后置处理器,bean的生命周期一共有7步
a 通过构造器创建bean实例(无参数构造)
b 为bean的属性设置值和对其他bean的引用(调用类中的set方法)
c 把bean的实例传递给bean的后置处理器的方法postProcessBeforeInitialization
d 调用bean的初始化方法(需要进行配置)
e 把bean的实例传递给bean的后置处理器的方法postProcessAfterInitialization
f bean可以使用了(对象获取到了)
g 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
5、演示调价后置处理器的效果
a 创建一个类实现接口BeanPostProcessor

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行此方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行此方法");
        return bean;
    }
}
 <bean id="myBeanPost" class="com.sunrise.spring5.bean.MyBeanPost"></bean>

第一步执行无参数的构造创建bean实例
第二部 调用set方法设置值
在初始化之前执行此方法
第三步 执行初始化方法
在初始化之后执行此方法
第四步, 获取创建bean实例的对象
com.sunrise.spring5.bean.Orders@4671e53b
第五步 执行销毁方法

IOC操作Bean管理(xml自动装配)

1、什么时自动装配
根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
2、演示自动装配的过程
- 根据属性名称自动注入

<!--    实现自动装配
            bean标签属性autowire,配置自动装配
            autowire属性常用的两个值,
             byName根据属性名称注入,注入值bean的id值和类的属性名称必须一样
              byType根据属性类型注入, -->
    <bean id="emp" class="com.sunrise.spring5.autowire.Emp" autowire="byName">
<!--        <property name="deot" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.sunrise.spring5.autowire.Dept"></bean>
- 根据属性类型自动注入
<!--    实现自动装配
            bean标签属性autowire,配置自动装配
            autowire属性常用的两个值,
             byName根据属性名称注入,注入值bean的id值和类的属性名称必须一样
              byType根据属性类型注入, -->
    <bean id="emp" class="com.sunrise.spring5.autowire.Emp" autowire="byType">
<!--        <property name="deot" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.sunrise.spring5.autowire.Dept"></bean>

IOC操作Bean管理(外部属性文件)

1、直接配置数据库信息
- 配置连接池
- 引入德鲁伊连接池jar包

<!--直接配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

2、通过引入外部属性文件配置数据库连接池
- 创建一个外部属性文件,properties格式文件,

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root
- 把外部properties属性文件引入到spring配置文件中
- 引入context名称空间
<?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:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
- 在spring配置文件中使用标签引入外部属性文件
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <!-- 获取properties文件内容,根据key获取,使用spring表达式获取 -->
            <property name="driverClassName" value="${prop.driverClass}"></property>
            <property name="url" value="${prop.url}"></property>
            <property name="username" value="${prop.userName}"></property>
            <property name="password" value="${prop.password}"></property>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值