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

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

  • 前言
    • 一、基于 xml 方式创建对象
    • 二、基于 xml 方式注入属性
      • 1. 使用 set 方法进行属性注入
      • 2. 使用有参数构造进行属性注入
      • 3. p 名称空间注入简化操作(了解)
    • 三、xml 注入其它类型属性
      • 1. 字面量
      • 2. 注入属性-外部 bean
      • 3. 注入属性-内部 bean
      • 4. 注入属性-级联赋值
    • 四、xml 注入集合属性
      • 1. 注入数组类型属性
      • 2. 注入 List 集合类型属性
      • 3. 注入 Map 集合类型属性
      • 4. 在集合里面设置对象类型值
      • 5. 把集合注入部分提取出来
    • 五、bean作用域
    • 六、bean 生命周期
    • 七、xml 自动装配
    • 八、外部属性文件
    • 九、FactoryBean



前言

本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习,欢迎关注!

一、基于 xml 方式创建对象

在这里插入图片描述

⭕在 spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建

⭕在 bean 标签有很多属性,介绍常用的属性

  • id 属性:唯一标识
  • class 属性:类全路径(包类路径)
  • name属性:作用与id属性一致,区别是name属性里面可以用特殊字符,但现在很少用name属性了

⭕创建对象时候,默认也是执行无参数构造方法完成对象创建,如果在类里用有参构造器覆盖无参构造器,运行时则会报错。

二、基于 xml 方式注入属性

DI:依赖注入,就是注入属性

1. 使用 set 方法进行属性注入

① 创建类,定义属性和对应的 set 方法

//演示使用 set 方法进行注入属性
public class Person {
    private String name;
    private String food;


    public void setName(String name) {
        this.name = name;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public void eat(){
        System.out.println(this.name+"吃"+this.food);
    }

}

② 在 spring 配置文件配置对象创建,配置属性注入

<!--配置 Person 对象创建-->
    <bean id="person_ir" class="com.ir.spring5.Person">
        
        <!--使用 property 完成属性注入
            name:类里面属性名称
            value:向属性注入的值
        -->
        <property name="name" value="小老师ir"></property>
        <property name="food" value="java"></property>
    </bean>

property标签中的属性name是相应的类中的属性名,value是指要赋予属性的值

③ 测试代码:

 @Test                                                                                      
 public void testEat(){                                                                     
     //1.加载spring配置文件                                                                       
     ApplicationContext context = new ClassPathXmlApplicationContext("person1.xml");        
     //2. 获取配置创建的对象                                                                         
     Person person = context.getBean("person_ir",Person.class);                             
     //3. 测试                                                                                
     System.out.println(person);//com.ir.spring5.Person@1b26f7b2                            
     person.eat(); //[小老师ir]吃java                                                           
                                                                                            
 }                                                                                          

2. 使用有参数构造进行属性注入

① 创建类,定义属性,创建属性对应有参数构造方法

package com.ir.spring5;

public class Car {
    private String number;
    private String speed;

    public Car(String number, String speed) {
        this.number = number;
        this.speed = speed;
    }

    public void run(){
        System.out.println(number+"::"+speed);
    }
}

② 在 spring 配置文件中进行配置

 <!--配置 Car 对象创建-->
    <bean id="car_ir" class="com.ir.spring5.Car">
    <!--有参数构造注入属性-->
      <!--方式1:通过name属性来确定类中的属性名-->
      <constructor-arg name="number" value="01"></constructor-arg>
      <constructor-arg name="speed" value="200"></constructor-arg>
        <!--方式2:通过索引来确定属性名-->
<!--  <constructor-arg index="0" value="01"></constructor-arg>-->
<!--  <constructor-arg index="1" value="200"></constructor-arg>-->
      
    </bean>

测试:

  @Test                                                                                      
 public void testCar(){                                                                     
     //1.加载配置文件                                                                             
     ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");          
     //2.获取配置文件创建的对象                                                                        
     Car car = context.getBean("car_ir",Car.class);                                         
     //3.测试                                                                                 
     System.out.println(car);//com.ir.spring5.Car@a74868d                                   
     car.run();//01::200                                                                    
 }                                                                                                                                                       

3. p 名称空间注入简化操作(了解)

使用 p 名称空间注入,可以简化基于 xml 配置方式

① 添加 p 名称空间在配置文件中
在这里插入图片描述

② 进行属性注入,在 bean 标签里面进行操作

<bean id="person_ir" class="com.ir.spring5.Person"  p:name="小老师ir" p:food="c++">
</bean>

三、xml 注入其它类型属性

1. 字面量

⭕ null 值

    <bean id="person_ir" class="com.ir.spring5.Person">
        <property name="name" >
            <null/>
        </property>
        <property name="food" value="java"></property>
    </bean>
@Test                                                                            
public void testEat(){                                                                                                                  
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");                                                         
    Person person = context.getBean("person_ir",Person.class);                                                                                      
    System.out.println(person);//com.ir.spring5.Person@1b26f7b2                  
    person.eat(); //[null]吃java                                                  

⭕ 属性值包含特殊符号

● 方法一:把<>进行转义 &lt; &gt;

 <bean id="person_ir" class="com.ir.spring5.Person">
        <property name="name" value="&lt;小老师ir&gt;"></property>
        <property name="food" value="java"></property>
 </bean>
@Test                                                                            
public void testEat(){                                                                                                                 
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");                                                            
    Person person = context.getBean("person_ir",Person.class);                                                                                
    System.out.println(person);//com.ir.spring5.Person@a74868d              
    person.eat(); //<小老师ir>吃java                                                  

● 方法二:把带特殊符号内容写到 CDATA

   <bean id="person_ir" class="com.ir.spring5.Person">
        <property name="name" >
            <value>
                <![CDATA[<<小老师ir>>]]>
            </value>
        </property>
        <property name="food" value="java"></property>
    </bean>
@Test                                                                            
public void testEat(){                                                           
    //1.加载spring配置文件                                                             
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    //2. 获取配置创建的对象                                                               
    Person person = context.getBean("person_ir",Person.class);                   
    //3. 测试                                                                      
    System.out.println(person);//com.ir.spring5.Person@a74868d                   
    person.eat(); //[<<小老师ir>>]吃java                                             

2. 注入属性-外部 bean

演示步骤:
① 创建两个类 service 类和 dao 类

② 在 service 调用 dao 里面的方法

UserDao

package Dao;

/**
 * @author shkstart
 * @create 2022-05-07 23:08
 */
public interface UserDao {
    public void update();
}

UserService

package Service;

import Dao.UserDao;

/**
 * @author shkstart
 * @create 2022-05-07 23:08
 */
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();
    }
}

UserDaoImpl

package Dao;

/**
 * @author shkstart
 * @create 2022-05-07 23:08
 */
public class UserDaoImpl implements UserDao{
    @Override
    public void update() {
        System.out.println("dao update...........");
    }
}

③ 在 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: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 https://www.springframework.org/schema/util/spring-util.xsd">
    <!--创建 UserService 对象-->
    <bean id="userservice" class="Service.UserService">
        <!--注入 userDao 对象
           name 属性:类里面属性名称
           ref 属性:创建 userDao 对象 bean 标签 id 值
        -->
        <property name="userDao" ref="userdaoimpl"></property>
    </bean>

    <!--创建 UserDaoImpl 对象-->
    <bean id="userdaoimpl" class="Dao.UserDaoImpl"></bean>


</beans>

测试:

@Test
   public void testBean(){
       ApplicationContext context1 = new ClassPathXmlApplicationContext("bean2.xml");
       UserService userService = (UserService)context1.getBean("userservice");
       System.out.println(userService);//Service.UserService@eafc191
       userService.add();
//       service add...............
//       dao update...........
  
   }

3. 注入属性-内部 bean

① 一对多关系:部门和员工,一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多
② 在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示

部门类

package Bean;
public class Dept {
    private String dname;
    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "dname='" + dname + '\'' +
                '}';
    }
}

员工类

package Bean;

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

    public void add() {
        System.out.println(ename+"::"+gender+"::"+dept);
    }
}

③ 在 spring 配置文件中进行配置

<!--内部bean-->
    <bean id="emp" class="Bean.Emp">
        <!--设置两个属性-->
        <property name="ename" value="小老师ir"></property>
        <property name="gender" value=""></property>

        <!--设置对象类型属性-->
        <property name="dept">
            <bean id="dept" class="Bean.Dept">
                <property name="dname" value="安保部"></property>
            </bean>
        </property>
    </bean>

测试

   @Test
   public void testEmp(){
       ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
       Emp emp = (Emp)context.getBean("emp");
       System.out.println(emp);//Bean.Emp@69b0fd6f
       emp.add();//小老师ir::女::Dept{dname='安保部'}

   }

4. 注入属性-级联赋值

方式一:

在 spring 配置文件bean4.xml中进行配置

<!--级联赋值-->
    <bean id="emp" class="Bean.Emp">
        <!--设置两个普通属性-->
        <property name="ename" value="小老师ir"></property>
        <property name="gender" value=""></property>

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

测试:

@Test
   public void testEmp2(){
       ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
       Emp emp = (Emp)context.getBean("emp");
       System.out.println(emp);//Bean.Emp@462d5aee
       emp.add();//小老师ir::女::Dept{dname='技术部'}
   }

方式二:员工属于某一个部门,使用对象形式表示

 <!--级联赋值-->
    <bean id="emp" class="Bean.Emp">
        <!--设置两个普通属性-->
        <property name="ename" value="小老师ir"></property>
        <property name="gender" value=""></property>

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

测试:

   @Test
   public void testEmp3(){
       ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
       Emp emp = (Emp)context.getBean("emp");
       System.out.println(emp);//Bean.Emp@757942a1
       emp.add();//小老师ir::女::Dept{dname='技术部'}
   }

注意:此种方法中,Emp类中必须有getDept( )方法

在这里插入图片描述

四、xml 注入集合属性

1. 注入数组类型属性

2. 注入 List 集合类型属性

3. 注入 Map 集合类型属性

步骤:

① 创建类,定义数组、list、map、set 类型属性,生成对应 set 方法

Stu类

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;


    public void setSets(Set<String> sets) {
        this.sets = sets;
    }
    public void setCourses(String[] courses) {
        this.courses = courses;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }

    @Override
    public String toString() {
        return "Stu{" +
                "courses=" + Arrays.toString(courses) +
                ", list=" + list +
                ", maps=" + maps +
                ", sets=" + sets +               
                '}';
    }
}

② 在 spring 配置文件进行配置

 <bean id="student" class="collectiontest.Stu"> 	
        <!--注入数组属性-->
        <property name="courses">
            <array >
                <value>Java</value>
                <value>C++</value>
            </array>
        </property>

        <!--注入list属性-->
        <property name="list">
            <list>
                <value>Python</value>
                <value>Go</value>
            </list>
        </property>

        <!--注入map属性-->
        <property name="maps">
            <map>
                <entry key="小老师ir" value="Java"></entry>
                <entry key="小老师ir" value="C++"></entry>
            </map>
        </property>

        <!--注入set属性-->
        <property name="sets">
            <set>
                <value>喜羊羊</value>
                <value>美羊羊</value>
            </set>
        </property>
    </bean>

测试:

  @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Stu student = context.getBean("student",Stu.class);
       System.out.println(student);//Stu{courses=[Java, C++], list=[Python, Go], maps={小老师ir=C++}, sets=[喜羊羊, 美羊羊]}
    }

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

Stu类

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;
    //学生所学多门课程
    private List<Course> courseList;
    public void setCourseList(List<Course> courseList) {
        this.courseList = courseList;
    }
    public void setSets(Set<String> sets) {
        this.sets = sets;
    }
    public void setCourses(String[] courses) {
        this.courses = courses;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }
    @Override
    public String toString() {
        return "Stu{" +
                "courses=" + Arrays.toString(courses) +
                ", list=" + list +
                ", maps=" + maps +
                ", sets=" + sets +
                ", courseList=" + courseList +
                '}';
    }
}

Course类

//课程类
public class Course {
    private String cname; //课程名称
    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}

在 spring 配置文件进行配置

<!--创建多个 course 对象-->
    <bean id="course1" class="collectiontest.Course">
        <property name="cname" value="英语课"></property>
    </bean>
    <bean id="course2" class="collectiontest.Course">
        <property name="cname" value="语文课"></property>
    </bean>
    <bean id="course3" class="collectiontest.Course">
        <property name="cname" value="数学课"></property>
    </bean>

    <!--创建Stu对象-->
    <bean id="student1" class="collectiontest.Stu">
        <!--注入 list 集合类型,值是对象-->
        <property name="courseList">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
                <ref bean="course3"></ref>
            </list>
        </property>
    </bean>

测试

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Stu student = context.getBean("student1",Stu.class);
        System.out.println(student);//Stu{courses=null, list=null, maps=null, sets=null, courseList=[Course{cname='英语课'}, Course{cname='语文课'}, Course{cname='数学课'}]}
    }

5. 把集合注入部分提取出来

Book类·

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

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

步骤:

① 在 spring 配置文件中引入名称空间 util

在这里插入图片描述

② 在 spring 配置文件进行配置,使用 util 标签完成 list 集合注入提取

<!--1 提取list集合类型属性注入-->
    <util:list id="bookList">
        <value>java</value>
        <value>c++</value>
        <value>python</value>
    </util:list>

    <!--2 提取list集合类型属性注入使用-->
    <bean id="book" class="collectiontest.Book" scope="prototype">
        <property name="list" ref="bookList"></property>
    </bean>

测试

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book= context.getBean("book", Book.class);
        System.out.println(book);//Book{list=[java, c++, python]}
    }

五、bean作用域

⭕ 在 Spring 里面,设置创建 bean 实例是单实例还是多实例 ?
⭕在 Spring 里面,默认情况下,bean 是单实例对象

Book类

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

在 spring 配置文件进行配置

<!--1 提取list集合类型属性注入-->
    <util:list id="bookList">
        <value>java</value>
        <value>c++</value>
        <value>python</value>
    </util:list>

    <!--2 提取list集合类型属性注入使用-->
    <bean id="book" class="collectiontest.Book" >
        <property name="list" ref="bookList"></property>
    </bean>

测试:

 @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book1= context.getBean("book", Book.class);
        Book book2= context.getBean("book", Book.class);
        System.out.println(book1);//collectiontest.Book@27d415d9
        System.out.println(book2);//collectiontest.Book@27d415d9
    }

由以上测试输出结果可知,创建的两个book对象地址相同,即为其实是同一个对象

⭕如何设置单实例还是多实例
● 在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
● scope 属性值,其中有两个常见的词

  1. 第一个值,默认值,singleton,表示是单实例对象
  2. 第二个值prototype,表示是多实例对象 Book类与如上相同

在 spring 配置文件进行配置

    <!--1 提取list集合类型属性注入-->
    <util:list id="bookList">
        <value>java</value>
        <value>c++</value>
        <value>python</value>
    </util:list>

    <!--2 提取list集合类型属性注入使用-->
    <bean id="book" class="collectiontest.Book" scope="prototype">
        <property name="list" ref="bookList"></property>y
    </bean>

测试:

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book1= context.getBean("book", Book.class);
        Book book2= context.getBean("book", Book.class);
        System.out.println(book1);//collectiontest.Book@27d415d9
        System.out.println(book2);//collectiontest.Book@5c18298f
    }

由以上测试输出结果可知,创建的两个book对象地址不相同,即为是两个对象

⭕ singleton 和 prototype 区别

● singleton 单实例,prototype 多实例

● 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象
● 设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,而是在调用getBean 方法时候创建多实例对象

六、bean 生命周期

⭕ 生命周期:从对象创建到对象销毁的过程

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

⭕ 演示 bean 生命周期

Order类

public class Order {
    private String name;

    public Order() {
        System.out.println("第一步:执行无参构造器创建对象");
    }
    public void setName(String name) {
        this.name = name;
        System.out.println("第二步:调用set()方法设置属性值");
    }
    public void initMethod(){
        System.out.println("第三步:执行初始化方法");
    }
    public void destroyMethod(){
        System.out.println("第五步:执行销毁的方法");
    }

}

在 spring 配置文件进行配置

<bean id="order" class="collectiontest.Order" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="电脑订单"></property>
</bean>

测试:

@Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        Order order= context.getBean("order", Order.class);
        System.out.println("第四步:获取创建 bean 实例对象");
        System.out.println(order);
        context.close();
//        第一步:执行无参构造器创建对象
//        第二步:调用set()方法设置属性值
//        第三步:执行初始化方法
//        第四步:获取创建 bean 实例对象
//        collectiontest.Order@4a87761d
//        第五步:执行销毁的方法
    }

⭕ bean 的后置处理器,bean 生命周期有七步

(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用bean 的销毁的方法(需要进行配置销毁的方法)

⭕ 演示添加后置处理器效果

(1)创建类,实现接口 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;
    }
}

在 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">

   <!--配置order对象-->
    <bean id="order" class="bean.Order" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="电脑订单"></property>
    </bean>

    <!--配置后置处理器-->
    <bean id="mybeanpost" class="bean.MyBeanPost"></bean>
</beans>

测试:

 @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        Order order= context.getBean("order", Order.class);
        System.out.println("第四步:获取对象");
        System.out.println(order);
        context.close();
//        第一步:执行无参构造器创建对象
//        第二步:调用set()方法设置属性值
//        在初始化之前执行的方法
//        第三步:执行初始化方法
//        在初始化之后执行的方法
//        第四步:获取对象
//        bean.Order@37374a5e
//        第五步:执行销毁的方法
    }

七、xml 自动装配

⭕ 什么是自动装配?

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

① bean 标签属性 autowire,配置自动装配
② autowire 属性常用两个值:

  1. byName:根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
  2. byType :根据属性类型注入

⭕演示自动装配过程
● 根据属性名称自动注入
Dept类

public class Dept {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

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

Emp类

public class Emp {
    private Dept dept;

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

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

在 spring 配置文件进行配置

<!--创建emp对象-->

    <!--使用自动装配方式注入属性:通过属性名的方式-->
    <bean id="emp" class="bean.Emp" autowire="byName">
        
        <!--使用手动方式注入属性-->
<!--        <property name="dept" ref="dept"></property>-->
    </bean>

<!--创建dept对象-->
    <bean id="dept" class="bean.Dept">
        <property name="name" value="技术部"></property>
    </bean>

测试:

 @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean5.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);//Emp{dept=Dept{name='技术部'}}
    }

● 根据属性类型自动注入

 <!--创建emp对象-->
    <!--使用自动装配方式注入属性:通过属性类型的方式-->
    <bean id="emp" class="bean.Emp" autowire="byType">

        <!--使用手动方式注入属性-->
<!--        <property name="dept" ref="dept"></property>-->
    </bean>

<!--创建dept对象-->
    <bean id="dept" class="bean.Dept">
        <property name="name" value="技术部"></property>
    </bean>

测试:

 @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean5.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);//Emp{dept=Dept{name='技术部'}}
    }

注意:通过属性类型的方式自动装配时,同一类型不能有多个bean对象,否则会报错

八、外部属性文件

⭕ 直接配置数据库信息

① 引入德鲁伊连接池依赖 jar 包
② 配置德鲁伊连接池

<!--创建数据库连接池对象-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--直接对连接池进行属性配置-->
        <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>

⭕ 引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties 格式文件,写数据库信息

jdbc.properties

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root

(2)把外部 properties 属性文件引入到 spring 配置文件中

① 引入 context 名称空间
在这里插入图片描述
② 在 spring 配置文件使用标签引入外部属性文件

<!--引入外部属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

<!--创建数据库连接池对象-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!--对连接池进行属性配置-->
        <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>

九、FactoryBean

Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)

  1. 普通 bean:在配置文件中定义 bean 类型就是返回类型
  2. 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样

步骤:

① 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
② 实现口里面的方法,在实现的方法中定义返回的bean 类型

Course类

public class Course {
    private String cname; //课程名称
    public void setCname(String cname) {
        this.cname = cname;
    }
    public String getCname(){
        return this.cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}
public class MyBean implements FactoryBean<Course> {
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("Java");
        return course;
    }

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

③ 在 spring 配置文件进行配置

<!--创建MyBean对象-->
    <bean id="mybean" class="factorybean.MyBean"></bean>

测试:

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Course course= context.getBean("mybean", Course.class);
        System.out.println(course.getCname());//Java
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/3163.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【云原生之企业级容器技术 Docker实战一】Docker 介绍

目录一、Docker 介绍1.1 容器历史1.2 Docker 是什么1.3 Docker 和虚拟机&#xff0c;物理主机1.4 Docker 的组成1.5 Namespace1.6 Control groups1.7 容器管理工具1.8 Docker 的优势1.9 Docker 的缺点1.10 容器的相关技术1.10.1 容器规范1.10.2 容器 runtime1.10.3 容器管理工具…

看齐iOS砍掉祖传功能,Android 16G内存也危险了

手机内存发展是真的迅速&#xff0c;12GB 没保持几年现在又朝着 16GB 普及。 相比 iOS 的墓碑机制&#xff0c;Android 后台就主打一个真实&#xff0c;只是可惜 APP 不那么老实。 如果你较早接触 Android 机&#xff0c;各种系统管理、优化 APP 的一键加速、清理应该还历历在…

AD9235芯片手册阅读笔记

特征 单个3 V电源操作&#xff08;2.7 V至3.6 V&#xff09; SNR70 dBc至65 MSPS时的奈奎斯特 SFDR85 dBc至65MSPS时奈奎斯特低功率&#xff1a; 300 mW至65 MSPS差分输入&#xff0c;带500 MHz带宽 片上参考和SHA DNL0.4 LSB 灵活模拟输入&#xff1a;1 V p-p至2 V p-p范围 偏…

Python的加密与解密,你知道几类?

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 据记载&#xff0c; 公元前400年&#xff0c; 古希腊人发明了置换密码。 1881年世界上的第一个电话 保密专利出现。 在第二次世界大战期间&#xff0c; 德国军方启用“恩尼格玛”密码机&#xff0…

[数据结构] 用两个队列实现栈详解

文章目录 一、队列实现栈的特点分析 1、1 具体分析 1、2 整体概括 二、队列模拟实现栈代码的实现 2、1 手撕 队列 代码 queue.h queue.c 2、2 用队列模拟实现栈代码 三、总结 &#x1f64b;‍♂️ 作者&#xff1a;Ggggggtm &#x1f64b;‍♂️ &#x1f440; 专栏&#xff1…

入职第一天就被迫离职,找工作多月已读不回,面试拿不到offer我该怎么办?

大多数情况下&#xff0c;测试员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 前言 前几天&#xff0c;我们一个粉丝跟我说&#xff0c;正常入职一家外包&#xff0c;什么都准备好了&#xff0…

Portainer堪称最优秀的容器化管理平台

一、Portainer是什么&#xff1f; Portainer是一款开源的容器管理平台&#xff0c;支持多种容器技术&#xff0c;如Docker、Kubernetes和Swarm等。它提供了一个易于使用的Web UI界面&#xff0c;可用于管理和监控容器和集群。Portainer旨在使容器管理更加简单和可视化&#xf…

WinForm | C# 界面弹出消息通知栏 (仿Win10系统通知栏)

ApeForms 弹出消息通知栏功能 文章目录ApeForms 弹出消息通知栏功能前言全局API通知栏起始方向通知排列方向通知栏之间的间隔距离无鼠标悬停时的不透明度消息通知窗体的默认大小示例代码文本消息提示栏文本消息提示栏&#xff08;带选项&#xff09;图文消息提示栏图文消息提示…

【Spring-boot源码剥析】| 启动原理之侠客行篇

目录一. 传说篇二. 快速启动原理三. 自动配置原理3.1 准备阶段3.2 配置阶段3.3 运行阶段三. Pefect Ending一. 传说篇 江湖传说&#xff0c;有一个神秘的江湖大侠&#xff0c;他名叫SpringBoot&#xff0c;擅长于开发出快速启动的应用程序。这个侠客的江湖名号传遍了整个江湖&a…

did not find expected key while parsing a block mapping at line 2 column 1的解决方法

问题描述 真的是困扰了好久的一个问题&#xff0c;真的是邪乎了&#xff0c;报的错误实际上是错的 完整报错&#xff1a; Error: YAML Exception reading /path_to_your_blog/_publications/2020-08-21.md: (<unknown>): did not find expected key while parsing a b…

JQuery

概述&#xff1a; JQuery&#xff1a;JavaScript和查询&#xff0c;他是辅助JavaScript开发的js类库。 他的的核心思想就是write less&#xff0c;do moire 实现了很多浏览器兼容问题 JQuery的核心函数 $(参数) 1 参数是函数&#xff1a;$(function(){}) window.onlooad fun…

AI风暴 :文心一言 VS GPT-4

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 文心一言 VS GPT-4 文心一言&#xff1a;知识增强大语言模型百度全新一代知识增强大语言模型&#xff0c;文心大模型家族的新成员&#xff0c;能够与人对话互动&#…

TryHackMe-Zeno(boot2root)

Zeno 你有和伟大的斯多葛派哲学家芝诺一样的耐心吗&#xff1f;试试吧&#xff01; 端口扫描 循例 nmap Web枚举 进到12340端口 目录扫描 /rms是一个业务站点 在admin登录页面尝试弱口令和注入&#xff0c;也都没有成功 SQLI 在点餐这发现了个get参数id&#xff0c;尝试sql…

八大排序算法之归并排序(递归实现+非递归实现)

目录 一.归并排序的基本思想 归并排序算法思想(排升序为例) 二.两个有序子序列(同一个数组中)的归并(排升序) 两个有序序列归并操作代码: 三.归并排序的递归实现 递归归并排序的实现:(后序遍历递归) 递归函数抽象分析: 四.非递归归并排序的实现 1.非递归归并排序算法…

如何从 Vue CLI 迁移到 Vite

如何从 Vue CLI 迁移到 Vite 十一月11 2021如果你在 2021 年之前一直在使用 Vue 进行开发&#xff0c;那么你选择的构建工具很有可能是 Vue CLI。一段时间以来&#xff0c;它一直是脚手架 Vue.js 项目的事实标准。不过现在&#xff0c;Evan You的下一代构建工具Vite已经引起了很…

精选7个 Python 学习资源库,助你成为优秀的开发者

当你在学习编程时&#xff0c;很容易被大量的资源所吓到&#xff0c;不知道该从何开始。 GitHub 仓库是一个很好的起点&#xff0c;因为它们提供了一种非常实用的方式来了解实际的编程应用。你可以查看其他人的代码&#xff0c;并将其与自己的代码进行比较和学习。 当涉及到 …

kubernetes(k8s)为容器和 Pod 分配内存资源

kubernetes(k8s)为容器和 Pod 分配内存资源 展示如何将内存请求&#xff08;request&#xff09;和内存限制&#xff08;limit&#xff09;分配给一个容器。 我们保障容器拥有它请求数量的内存&#xff0c;但不允许使用超过限制数量的内存。 创建新的命名空间 kubectl creat…

【数据结构】顺序栈的C语言实现

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录栈1. 栈的概念1.1 栈…

Java打开CSV文件到JTable展示

概述主要知识点SwingNode类 &#xff1a;把Java swing组件封装成一个JavaFX的Node&#xff0c;使得Java Swing可以和JavaFX嵌套在一起使用&#xff0c;JavaSwing贼丑&#xff0c;但操作简单&#xff0c;JavaFX的表格组件&#xff08;TableView等&#xff09;有点复杂&#xff0…

DevOps流水线搭建-PHP版本

一、介绍流水线发布代码1、官网https://www.jenkins.io/zh2、kubesphere里的介绍https://kubesphere.io/zh/docs/v3.3/devops-user-guide/how-to-use/pipelines/choose-jenkins-agent/3、git仓库可以自己写点测试代码&#xff0c;提交&#xff0c;待会测试用https://gitee.com/…
最新文章