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

IOC容器

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

IOC底层

通过控制反转,使用xml配置文件和反射机制实现对对象的创建

IOC接口

实现IOC容器的两种方式

(1)BeanFactory

Spring内部使用
加载配置文件时不会创建对象,只有在使用时创建对象

(2)ApplicationContext

BeanFactory的子接口,面向开发人员
加载配置文件时会创建对象

IOC容器实现类

① FileSystemXMLApplicationContext:参数为文件路径

② ClassPathXMLApplicationContext:参数为类路径

基于xml实现bean管理

1.创建对象

User.java

public class User {
    public void add(){
        System.out.println("add.......");
    }
}

bean.xml

<!--    1.配置User对象创建-->
    <bean id="user" class="com.lin.pojo.User"></bean>

(1)属性

  • id:唯一标识,对象别名,通过这个名字得到对象

  • class:将要创建对象的类全路径

(2)创建对象时默认执行无参构造

2.依赖注入
(1)setter方法注入:property

Book.java

@Data
public class Book {
    private String bname;

}

bean1.xml

        <!-- setter-->
<!--    1.创建对象-->
    <bean id="b" class="com.lin.pojo.Book">
        <!-- name:property name  value:将要注入的值-->
       <property name="bname" value="123"></property>
    </bean>

Test.java

    @Test
    public void test02(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");

        Book book1 = context.getBean("b", Book.class);
        System.out.println(book1.getBname());
    }
(2)有参构造方法注入:constructor-arg

Orders.java

@AllArgsConstructor
public class Orders {
    private String oname;
    private String address;

    @Override
    public String toString() {
        return this.address + " : " + this.oname;
    }
}

bean1.xml


        <!-- 有参构造-->
    <bean id="orders" class="com.lin.pojo.Orders">
        <constructor-arg name="oname" value="123"></constructor-arg>
        <constructor-arg name="address" value="456"></constructor-arg>
    </bean>
    
<!-- 或者-->

    <bean id="orders" class="com.lin.pojo.Orders">
    <!-- 通过有参构造方法参数的索引值匹配 -->
        <constructor-arg index="0" value="123"></constructor-arg>
        <constructor-arg index="1" value="456"></constructor-arg>
    </bean>

Test.java

    @Test
    public void test03(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
        Orders or = context.getBean("orders", Orders.class);
        System.out.println(or.toString());
    }
3.注入属性
(1)字面量
  • 空值null
<property name="address">
    <null></null>
</property>
  • 属性包含特殊符号,使用< value >标签
<!-- 1.转义字符 -->

<!-- 2.CD -->
       <property name="bname">
           <value>
               <![CDATA[<<Android>>]]>>
           </value>
       </property>
(2)外部bean
  1. 创建两个类service和dao
  2. 在service调用dao里面的方法
  3. 在spring配置文件进行配置

UserService.java

public class UserService {

    //创建UserDao属性并生成set方法
    private UserDao userDao;

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

    public void add(){
        System.out.println("add---------service");

        //service类调用dao
        //1.原始方式:new UserDaoImpl ,调用方法
        //2.spring:创建两个类,将UserDao注入到UserService
        userDao.update();
    }
}

UserDao.java

public interface UserDao {

    void update();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void update() {
        System.out.println("dao update---------");
    }
}

bean2.xml

<!--    1. service and dao create-->
    <bean id="service" class="com.lin.service.UserService">

<!--        2.注入UserDao对象  name:属性名  ref:将要注入对象的id-->
        <property name="userDao" ref="dao"></property>
    </bean>

    <bean id="dao" class="com.lin.dao.UserDaoImpl"></bean>
</beans>

Test02.java

@Test
    public void serviceAndDao(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        UserService service = context.getBean("service", UserService.class);
        service.add();
    }
(3)内部bean
  1. 一对多

  2. 在实体类中表示一对多的关系—在多的那方加入一

  3. spring配置文件配置

Emp.java

//员工类
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;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "ename='" + ename + '\'' +
                ", gender='" + gender + '\'' +
                ", dept=" + dept +
                '}';
    }
}

Dept.java

//部门类
public class Dept {
    private String dname;
    public void setDname(String dname){
        this.dname=dname;
    }
}

bean3.xml

<!--    内部bean-->
    <bean id="emp" class="com.lin.bean.Emp">
<!--        设置普通属性-->
        <property name="ename" value="tom"></property>
        <property name="gender" value="nv"></property>

<!--        对象类型属性-->
        <property name="dept">
            <bean id="dept" class="com.lin.bean.Dept">
                <property name="dname" value="aqy"></property>
            </bean>
        </property>
    </bean>

Test03.java

@Test
    public void Test01(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");
        Emp emp = context.getBean("emp", Emp.class);

        System.out.println(emp.toString());
    }
(4)级联赋值(与外部bean相似)

bean4.xml

<!--    级联赋值    第一种写法-->
    <bean id="emp" class="com.lin.bean.Emp">
        <!--        设置普通属性-->
        <property name="ename" value="tom"></property>
        <property name="gender" value="nv"></property>

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

    <bean id="dept" class="com.lin.bean.Dept">
        <property name="dname" value="cwb"></property>
    </bean>

     ------------------------------------------------------------------------------

        <!--    级联赋值    第二种写法-->
    <bean id="emp" class="com.lin.bean.Emp">
        <!--        设置普通属性-->
        <property name="ename" value="tom"></property>
        <property name="gender" value="nv"></property>

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

Test03.java

    @Test
    public void Test02(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
        Emp emp = context.getBean("emp", Emp.class);

        System.out.println(emp.toString());
    }
(5)注入集合
  1. 注入数组
  2. 注入List
  3. 注入Map
  4. 注入Set

Stu.java

public class Stu {
    //1.数组类型的属性
    private String[] courses;

    //2.List集合类型属性
    private List<String> list;

    //3.Map集合类型属性
    private Map<String,String> maps;

    //4.set集合类型的属性
    private Set<String> sets;

//setter省略

bean1.xml

<!--    集合类型属性的注入-->
    <bean id="stu" class="com.lin.collectiontype.Stu">
<!--        数组-->
        <property name="courses" >
            <array>
                <value>java</value>
                <value>c++</value>
            </array>
        </property>

<!--        list-->
        <property name="list">
            <list>
                <value>zhangs</value>
                <value>xiaosan</value>
            </list>
        </property>

<!--        Map-->
        <property name="maps">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry value="PHP" key="php"></entry>
            </map>
        </property>

<!--        set-->
        <property name="sets">
            <set>
                <value>MySQL</value>
                <value>Redis</value>
            </set>
        </property>
    </bean>

Test01.java

@Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

        Stu stu = context.getBean("stu", Stu.class);
        System.out.println(stu);
    }
4.在集合中设置对象类型的值

Course.java

public class Course {
    private String cname;

    // setter and toString omit
    
}

Stu.java

public class Stu {

    //学生所学多门课
    private List<Course> courseList;

    // setter and toString omit
}

bean1.xml

<!--    集合类型属性的注入-->
    <bean id="stu" class="com.lin.collectiontype.Stu">
    
<!--        List集合与对象-->
        <property name="courseList">
            <list>
<!--                   bean:对象bean的id-->
                <ref bean="c1"></ref>
                <ref bean="c2"></ref>
            </list>
        </property>
    </bean>

    <bean id="c1" class="com.lin.collectiontype.Course">
        <property name="cname" value="S"></property>
    </bean>
    <bean id="c2" class="com.lin.collectiontype.Course">
        <property name="cname" value="M"></property>
    </bean>

Test01.java

@Test
   public void test01(){
       ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

       Stu stu = context.getBean("stu", Stu.class);
       System.out.println(stu);
   }
5.集合注入的部分提取为公共
  1. 在spring配置文件中引入util名称空间

  2. 使用util标签完成list集合注入的提取

Book.java

public class Book {
    private List<String> list;

    public void setList(List<String> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "Book{" +
                "list=" + list +
                '}';
    }
}

bean2.xml

<!--    1.提取list集合属性-->
    <util:list id="bookL">
        <value>yjj</value>
        <value>jysg</value>
        <value>xlsbz</value>
    </util:list>

<!--    2.注入-->
    <bean id="book" class="com.lin.collectiontype.Book">
        <property name="list" ref="bookL"></property>
    </bean>

    <bean id="book2" class="com.lin.collectiontype.Book">
        <property name="list" ref="bookL"></property>
    </bean>

Test01.java

    @Test
    public void test02(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");

        Book book = context.getBean("book", Book.class);
        System.out.println(book);

        book=context.getBean("book2",Book.class);
        System.out.println(book);
    }
4、FactoryBean

Spring有两种类型的bean

  • 普通bean:在配置文件中,定义的bean的类型与返回类型一致
  • 工厂bean:在配置文件中,定义的bean的类型与返回的类型不一致
    • 创建类,让这个类作为工厂bean(实现FactoryBean接口)
    • 实现接口中的方法,在方法中定义返回类型

Mybean.java

  public class Mybean implements FactoryBean<Course> {

    //定义返回bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("abc");
        return course;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

bean3.xml

    <bean id="mybean" class="com.lin.collectiontype.com.lin.factoryBean.Mybean">

    </bean>

Test01.java

    @Test
    public void test03(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");

        Course course = context.getBean("mybean", Course.class);
        System.out.println(course);
    }
5.bean的作用域
  1. 在Spring里面,默认情况下,bean为单实例

  2. 设置单实例或者多实例

  • bean标签中的(scope)属性

    • 默认值,singleton:单实例,在加载spring配置文件的时候创建对象

    • prototype:多实例,在调用getBean方法的时候创建对象

6.bean的生命周期

1、

(1)创建bean实例(无参构造)

(2)属性值(setter)

(3)调用bean的初始化方法(init bean标签配置)

(4)获取bean实例(getBean)

(5)销毁bean(destroy bean标签配置)

2、bean的后置处理器

(1)创建bean实例(无参构造)

(2)属性值(setter)

(3) bean的实例传递给bean的后置处理器的方法

(4)调用bean的初始化方法(init bean标签配置)

(5) bean的实例传递给bean的后置处理器的方法

(6)获取bean实例(getBean)

(7)销毁bean(destroy bean标签配置)

xml自动装配

根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入

Dept.java、Emp.java

public class Dept {
    @Override
    public String toString() {
        return super.toString();
    }
}

public class Emp {

    private Dept dept;

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

    @Override
    public String toString() {
        return "Emp{" +
                "dept=" + dept +
                '}';
    }
}

bean5.xml

<!--    自动装配  属性-->
<!--    bean标签 autowire:
byName根据属性名称注入,bean id的值与属性名称一致
byType根据属性类型注入-->

    <bean id="emp" class="com.lin.autowire.Emp" autowire="byName"></bean>

    <bean id="dept" class="com.lin.autowire.Dept"></bean>

    <bean id="emp2" class="com.lin.autowire.Emp" autowire="byType"></bean>

test04.java

    @Test
    public void test04(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean5.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);
        Emp emp2 = context.getBean("emp2", Emp.class);
        System.out.println(emp2);
    }
引入外部属性文件
1.直接配置数据库信息

(1)连接池

bean6.xml

<!--    配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/lin?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
2.引入外部属性文件

(1)创建properties格式的属性文件,写数据库信息

jdbc.properties

prop.driverClass=com.alibaba.druid.pool.DruidDataSource
prop.url=jdbc:mysql://localhost:3306/lin?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC
prop.username=root
prop.password=123456

(2)把外部properties引入spring配置

  • 1.context名称空间

  • 2.引入外部文件

bean6.xml

<!--    引入外部文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    
<!--    配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <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>
    </bean>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值