spring5-ioc container-xml parsing-operation bean

What is IOC

(1) Inversion of control, hand over our object creation and calling process between objects to Spring for management

(2) Purpose of using IOC: to reduce coupling

(3) The introductory case is IOC implementation

The underlying principles of IOC

(1) xml parsing, factory mode, reflection

Please add image description
Please add image description

(2) IOC process:

Insert image description here

IOC interface (BeanFactory)
  1. The IOC idea is based on the IOC container. The bottom layer of the IOC container is the object factory.

  2. Spring provides two ways to implement IOC containers: (two interfaces)

    (1) BeanFactory: The basic implementation of the IOC container is an interface used internally by spring and is not available to developers.

    • The object will not be created when loading the configuration file. The object will be created after the object is obtained (used).

    (2) ApplicationContext: A sub-interface of the BeanFactory interface, providing more powerful functions, generally

    Used by developers.

    • When loading the configuration file, the configuration file object will be created.
  3. The ApplicationContext interface has implementation classes

Insert image description here

IOC operation bean management (based on xml)
  1. What is bean management

    • Bean management refers to two operations

    (1) Spring creates objects

    (2) Spring injection properties

  2. There are two ways to operate Bean

    (1) Implemented based on xml configuration file

    <!--      配置User对象创建-->
        <bean id="user" class="spring5.User"></bean>
    
    • In the configuration file, use the bean tag and add the corresponding attributes to the tag to create the object.

    • There are many attributes in the bean tag. Let’s introduce the commonly used attributes.

      (1) id attribute: unique identification

      (2) class: full path of the class (including full path)

      (3) When creating an object, the default is to execute the parameterless construction method to complete the object creation.

    (2) Inject attributes based on xml

    DI: Dependency injection, which is to inject properties

    ​ The first injection method: use the set method to inject

    package spring5;
    
    /**
     * 演示使用set方法进行注入属性
     */
    public class Book {
          
          
        private String bname;
        private String bauthor;
        //set方法注入
        public void setBname(String bname){
          
          
            this.bname=bname;
        }
        public void setBauthor(String bauthor) {
          
          
            this.bauthor = bauthor;
        }
        public void testBook(){
          
          
            System.out.println(bname+","+bauthor);
        }
    }
    
    <bean id="book" class="spring5.Book">
        <property name="bname" value="天龙八部"></property>
        <property name="bauthor" value="金庸"></property>
    </bean>
    
        @Test
        public void testBook(){
          
          
    //        加载spring配置文件
            ApplicationContext context=
                    new ClassPathXmlApplicationContext("bean1.xml");
    //        获取配置创建对象
            Book book=context.getBean("book", Book.class);
            System.out.println(book);
            book.testBook();
        }
    

    ​The second injection method: using parameterized construction

    public class Orders {
          
          
        private String oname;
        private String address;
        public Orders(String oname, String address) {
          
          
            this.oname = oname;
            this.address = address;
        }
    }
    
    <!--    使用有参构造注入属性-->
        <bean id="orders" class="spring5.Orders">
            <constructor-arg name="oname" value="abc"></constructor-arg>
            <constructor-arg name="address" value="陕西省"></constructor-arg>
        </bean>
    
    @Test
    public void testOrders(){
    
    
//        加载spring配置文件
        ApplicationContext context=
                new ClassPathXmlApplicationContext("bean1.xml");
//        获取配置创建对象
        Orders orders=context.getBean("orders", Orders.class);
        System.out.println(orders);
        orders.testOrders();
    }

​ The third injection method: use p namespace injection

​ (1) Using p namespace injection can simplify the xml-based configuration method (the bottom layer is also set method injection)

<?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="book" class="spring5.Book" p:bname="水浒传" p:bauthor="施耐庵"></bean>
  • The use of two angle brackets:
<!-- &lt;&lt; &gt;&gt;  两个尖括号-->
<!-- <![CDATA[<<金庸>>]]>-->
<bean id="book" class="spring5.Book">
    <property name="bname" value="&lt;&lt;天龙八部&gt;&gt;"></property>
    <property name="bauthor">
        <value><![CDATA[<<金庸>>]]></value>
    </property>
</bean>
    

spring5.Book@173ed316
<<Dragon Babu>>,<<Jin Yong>>

  • Inject properties - external bean

    ​ (1) Create two classes, service class and dao class

    public interface UserDao {
          
          
        void update();
    }
    public class UserDaoImpi implements UserDao{
          
          
    
        @Override
        public void update() {
          
          
            System.out.println("dao update..............");
        }
    }
    
    public class UserService {
          
          
        //创建UserDao类型的属性,生成set方法
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
          
          
            this.userDao = userDao;
        }
        public void add(){
          
          
            System.out.println("service add...............");
            //原始方式
    //        UserDaoImpi userDaoImpi=new UserDaoImpi();
    //        userDaoImpi.update();
              userDao.update();
    
        }
    }
    
    public class UserService {
          
          
        //创建UserDao类型的属性,生成set方法
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
          
          
            this.userDao = userDao;
        }
        public void add(){
          
          
            System.out.println("service add...............");
            //原始方式
    //        UserDaoImpi userDaoImpi=new UserDaoImpi();
    //        userDaoImpi.update();
              userDao.update();
        }
    }
    
    <?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">
    <!--       service和dao对象创建-->
        <bean id="userService" class="spring5.service.UserService">
    <!--        注入userDao对象-->
    <!--        name属性:类里面有属性名称-->
    <!--        ref属性:创建userDao对象bean标签id值-->
            <property name="userDao" ref="userDaoImpi"></property>
         </bean>
        <bean id="userDaoImpi" class="spring5.dao.UserDaoImpi"></bean>
    
    </beans>
    

    (2) Call the method in dao in service

    public class TestBean {
          
          
        @Test
        public void testUserService(){
          
          
    //        加载spring配置文件
            ApplicationContext context=
                    new ClassPathXmlApplicationContext("bean2.xml");
    //        获取配置创建对象
            UserService userservice=context.getBean("userService", UserService.class);
            System.out.println(userservice);
            userservice.add();
        }
    }
    
  • Injecting properties - internal beans and cascading assignments

(1) One-to-many relationship: departments and employees

​A department has multiple employees, and one employee belongs to one department

​The department is one, but the employees are many

(2) Represent a one-to-many relationship between entity classes, employees represent the departments they belong to, and use the attributes of the object to represent them.

//部门类
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;
    }
}

    @Test
    public void testDept(){
    
    
//        加载spring配置文件
        ApplicationContext context=
                new ClassPathXmlApplicationContext("bean3.xml");
//        获取配置创建对象
        Emp emp=context.getBean("emp", Emp.class);
        System.out.println(emp);
        emp.add();
    }

(3) Configure in the spring configuration file (you can also set beans in the attribute property)

<!--       内部bean-->
    <bean id="emp" class="spring5.bean.Emp">
<!--        先设置两个普通的属性-->
        <property name="ename" value="lucy"></property>
        <property name="gender" value=""></property>
<!--        设置对象属性-->
        <property name="dept">
            <bean id="dept" class="spring5.bean.Dept">
                <property name="dname" value="保安部"></property>
            </bean>
        </property>
    </bean>

(4) Injection properties - cascade assignment (same as internal beans)

    <!--       内部bean-->
    <bean id="emp" class="spring5.bean.Emp">
        <!--        先设置两个普通的属性-->
        <property name="ename" value="lucy"></property>
        <property name="gender" value=""></property>
<!--        级联赋值-->
        <property name="dept" ref="dept"></property>
    </bean>
    <bean id="dept" class="spring5.bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>

    <bean id="emp" class="spring5.bean.Emp">
        <!--        先设置两个普通的属性-->
        <property name="ename" value="lucy"></property>
        <property name="gender" value=""></property>
<!--        级联赋值-->
        <property name="dept" ref="dept"></property>
        <property name="dept.dname" value="技术部"></property>  //设置get方法这里也可以
    </bean>
IOC operation bean management (based on annotations)
  • Inject collection property values
  1. Inject array type properties

  2. Inject List collection type properties

  3. Inject Map collection type properties

  4. Inject Set collection type properties

    (1) Create these collections and generate set methods

public class Stu {
    
    
    //1.数组类型的属性
    private String[] courses;
    //2.List集合类型属性
    private List<String> list;
    //3.创建一个Map集合属性
    private Map<String,String> map;
    private Set<String> set;

    public void setSet(Set<String> set) {
    
    
        this.set = set;
    }
    public void setList(List<String> list) {
    
    
        this.list = list;
    }
    public void setMap(Map<String, String> map) {
    
    
        this.map = map;
    }
    public void setCourses(String[] courses) {
    
    
        this.courses = courses;
    }
}
    @Test
    public void testCollection(){
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
        Stu stu=context.getBean("stu",Stu.class);
        stu.test();
    }

​ (2) Configure in the spring configuration file

<!--        集合类型属性的注入-->
       <bean id="stu" class="spring5.collectionType.Stu">
           <property name="courses">
               <array>
                   <value>java课程</value>
                   <value>数据库课程</value>
               </array>
           </property>
<!--           list集合-->
           <property name="list">
               <list>
                   <value>张安</value>
                   <value>王五</value>
               </list>
           </property>
<!--           map集合-->
           <property name="map">
               <map>
                   <entry key="张三" value=""></entry>
                   <entry key="李四" value=""></entry>
               </map>
           </property>
<!--           set集合-->
           <property name="set">
               <set>
                   <value>mysql</value>
                   <value>redis</value>
               </set>
           </property>
       </bean>
  • Inject collection object value

    (1) Set the object type value in the collection

    <!--           注入list集合类型,值是对象-->
               <property name="listCouse" >
                   <list>
                       <ref bean="couse1" ></ref>
                       <ref bean="couse2" ></ref>
                       <ref bean="couse3" ></ref>
                   </list>
               </property>
               
    <!--    创建多个couse对象-->
        <bean id="couse1" class="spring5.collectionType.Couse">
            <property name="cname" value="spring框架"></property>
        </bean>
        <bean id="couse2" class="spring5.collectionType.Couse">
            <property name="cname" value="mysql"></property>
        </bean>
        <bean id="couse3" class="spring5.collectionType.Couse">
            <property name="cname" value="java"></property>
        </bean>
    

    (2) Extract the collection injection part and make it a public part

    First introduce a namespace util in the spring configuration file

    <?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">
    <!--        集合类型属性的注入-->
    </beans>
    
<!--        集合类型属性的注入-->
        <util:list id="bookList">
            <value>易筋经</value>
            <value>九阴真经</value>
            <value>酒养生功</value>
        </util:list>
<!--    提取lsit集合属性注入使用-->
    <bean id="book" class="spring5.collectionType.Book">
        <property name="list" ref="bookList">
        </property>
    </bean>
IOC operation bean management (FactoryBean)
  1. Spring has two types of beans, one is ordinary beans and the other is factory beans.

  2. Ordinary bean: The type defined in the configuration file is the type returned in the file

  3. Factory bean: the defined type can be different from the returned type

    • The first step is to create a class, let this be used as a factory bean, and implement the interface FactoryBean
    public class Mybean implements FactoryBean<Couse> {
          
          
        //定义返回Bean
        @Override
        public Couse getObject() throws Exception {
          
          
            Couse couse=new Couse();
            couse.setCname("aaaa");
            return couse;
        }
        @Override
        public Class<?> getObjectType() {
          
          
            return null;
        }
    }
        @Test
        public void test3(){
          
          
            ApplicationContext context=new 					ClassPathXmlApplicationContext("bean3.xml");
            Couse mybean=context.getBean("myBean", Couse.class);
            System.out.println(mybean);
        }
    
    • The second step is to implement the methods in the interface and define the returned bean type in the implemented method.
<bean id="myBean" class="factorybean.Mybean.Mybean"></bean>

IOC operation bean management (Bean scope)

  1. In spring, set whether to create a bean instance as a single instance or multiple instances.
  2. In spring, by default, beans are single instance objects

Insert image description here

The address obtained is the same

  1. How to set whether it is a single instance or multiple instances

    (1) In the bean tag in the spring configuration file, there is

    (2) scope attribute value

    ​ The first value is the default value, singleton, which means it is a single instance.

    The second value prototype represents a multi-instance object.

    <bean id="myBean" class="factorybean.Mybean.Mybean" scope="prototype"></bean>
    

Insert image description here

​ The address values ​​obtained after setting to multiple instances are different.

(3) The difference between singleton and prototype

​ The first singleton is a single instance, and the prototype is multiple instances.

​ Second, when setting up singleton, an instance object will be created when loading the spring configuration file.

​ When setting the prototype, call the getBean method to create an instance object

Life cycle of IOC operation bean:
  1. life cycle

​ (1) The process from object creation to object destruction

  1. bean life cycle

    (1) Create a bena instance through the constructor (no-parameter construction)

    (2) Set values ​​for bean properties and reference other beans (call the set method)

    (3) Call the bean’s initialization method (configuration required)

    (4) The bean can be used (the object is obtained)

    (5) When the container is closed, call the bean's destruction method (need to configure the destruction method)

  2. Demo bean life cycle

public class Orders {
    
    
    public Orders() {
    
    
        System.out.println("第一步,执行 无参构造创建bean实例");
    }
    private String oname;
    public void setOname(String oname) {
    
    
        this.oname = oname;
        System.out.println("第二步 调用set方法设置属性值");
    }
    //创建执行的初始化方法
    public void  initMethod(){
    
    
        System.out.println("第三步 执行初始化的方法");
    }
    //创建执行销毁的方法
    public void destroyMethod(){
    
    
        System.out.println("第五步 执行销毁的方法");
    }
}
<bean id="orders" class="factorybean.Mybean.Orders" init-method="initMethod" destroy-method="destroyMethod">
       <property name="oname" value="手机"></property>
</bean>
    @Test
    public void testBean4(){
    
    
//        ApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
        //这里直接调用子接口
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
        Orders orders=context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建bean实例对象");
        System.out.println(orders);
        //手动bean实例销毁
//      ((ClassPathXmlApplicationContext) context).close();
        context.close();
    }

Run result:
The first step is to perform parameterless construction to create a bean instance
The second step is to call the set method to set the attribute value
The third step is to perform the initialization method
The fourth step is to obtain the created bean instance object
factorybean.Mybean.Orders@74d1dc36< a i=6> The fifth step is to execute the destruction method

  1. Bean post-processor, the bean life cycle has seven steps

    (1) Create a bena instance through the constructor (no-parameter construction)

    (2) Set values ​​for bean properties and reference other beans (call the set method)

    (3) Pass the bean instance to the bean postprocessor method

    postProcessBeforeInitialization
    

    (4) Call the bean’s initialization method (configuration required)

    (5) The method of passing the bean instance to the bean post-processor

    postProcessAfterInitialization
    

    (6) The bean can be used (the object is obtained)

    (7) When the container is closed, call the bean's destruction method (the destruction method needs to be configured)

  2. Demonstration of adding post-processor effects

    (1) Create a class, implement the interface BeanPostProcessor, and create a post-processor

public class MybeanPsot 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="factorybean.Mybean.MybeanPsot"></bean>

operation result:

The first step is to perform parameterless construction to create a bean instance
The second step is to call the set method to set the attribute value
and execute it "before" initialization Method
The third step is to execute the initialization method
The method is to be executed "after" initialization
The fourth step is to obtain the creation bean instance object
factorybean.Mybean.Orders@53045c6c
The fifth step is to execute the destruction method

IOC operation bean management (xml automatic assembly)

  1. What is autowiring

    (1) According to the specified assembly rule (property name or property type), Spring automatically injects the matching property value.

  2. Demonstrate automatic assembly process

    (1) Automatically inject according to attribute name

    <!--       后置处理器
               实现自动装配
               bean标签属性autowire,配置自动装配
               autowire属性常用两个值:
               byName根据属性名称注入 ,注入的值和类属性名称一一样
               byType根据属性类型注入,
    -->
           <bean id="emp" class="autowire.Emp" autowire="byName">
    <!--              <property name="dept" ref="dept"></property>-->
           </bean>
    <!--       引入外部bean-->
           <bean id="dept" class="autowire.Dept"></bean>
    
    		// 根据属性类型进行注入,但是有多个类型会报错
           <bean id="emp" class="autowire.Emp" autowire="byType">
    <!--              <property name="dept" ref="dept"></property>-->
           </bean>
    <!--       引入外部bean-->
           <bean id="dept" class="autowire.Dept"></bean>
    </beans>
    
IOC operation bean management (external properties file)
  1. Configure database information directly

    (1) Configure Druid connection pool

    (2) Introducing the Druid connection pool dependent jar package

    <!--       直接配置连接池-->
           <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>
    
  2. Introducing external properties to configure the database connection pool

    (1) Create external property files, properties format files, and write database information

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

    (2) Introduce the external properties file into the spring configuration file

    ​ *Introduce context namespace

    <?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: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">
    <!--       直接配置连接池-->
           <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>
    </beans>
    

Guess you like

Origin blog.csdn.net/qq_14930709/article/details/124327504