[Spring] Bean scope, factory mode, Bean acquisition method and other key knowledge summary

1. Single case and multiple cases (Bean scope):

  • How Spring manages this bean by default:

  • Bean is a singleton by default (singleton: singleton)

  • Instantiate when the Spring context is initialized

  • Every time the getBean() method is called, the singleton object is returned

// xml
// scope默认情况下就是singleton单例的
<bean id="dog" class="com.powernode.bean.Dog"></bean>

// @Test
public void test(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Dog dog1 = ctx.getBean("dog", Dog.class);
    System.out.println(dog1);// com.powernode.bean.Dog@4e41089d

    Dog dog2 = ctx.getBean("dog", Dog.class);
    System.out.println(dog2);// com.powernode.bean.Dog@4e41089d

    Dog dog3 = ctx.getBean("dog", Dog.class);
    System.out.println(dog3);// com.powernode.bean.Dog@4e41089d
}
  • When setting the scope property of the bean to prototype

  • bean is multiple instance

  • When the spring context is initialized, these prototype beans are not initialized

  • Each time the getBean() method is called, the bean object is instantiated

  • prototype translates as: prototype

// xml
<bean id="dog" class="com.powernode.bean.Dog" scope="prototype"></bean>
      
// @Test
public void test(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Dog dog1 = ctx.getBean("dog", Dog.class);
    // 构造方法执行!
	// com.powernode.bean.Dog@4e41089d
    System.out.println(dog1);

    Dog dog2 = ctx.getBean("dog", Dog.class);
    // 构造方法执行!
	// com.powernode.bean.Dog@32a068d1
    System.out.println(dog2);

    Dog dog3 = ctx.getBean("dog", Dog.class);
    // 构造方法执行!
	// com.powernode.bean.Dog@33cb5951
    System.out.println(dog3);
}
  • The value of the scope attribute:

  • singleton: singleton

  • prototype: prototype/multiple instances

After introducing the springMVC framework:

  • request: a bean in a request, only used in WEB applications

  • session: There is only one bean in a session, only used in WEB applications

2. Factory model of GoF:

  • Design Patterns: A Reusable Solution

2.1 Three forms of factory mode:

  • Simple factory pattern: not one of the 23 design patterns, also known as static factory method pattern, simple factory pattern is a special implementation of factory method pattern

  • Factory method pattern: one of the 23 design patterns

  • Abstract factory pattern: one of the 23 design patterns

2.2 Simple factory mode:

  • The simple factory pattern is a special implementation of the factory method pattern , also known as: static factory method pattern

  • What problem does the simple factory pattern solve?

  • The client program does not need to care about the details of object creation. When it needs an object, it only needs to ask the factory for it. The separation of responsibilities is initially realized. The client is only responsible for consumption, and the factory is responsible for production. Production and consumption are separated.

  • Roles in the simple factory pattern:

  • Abstract product role Weapon

  • Specific product role Gun

  • Factory class role WeaponFactory

  • Disadvantages of the simple factory pattern:

  • Disadvantage 1: The factory class concentrates the creation logic of all products, forming an omniscient and omnipotent class. The factory class is very critical and cannot cause problems. Once a problem occurs, the entire system will be paralyzed

  • Disadvantage 2: It does not conform to the principle of OCP opening and closing . When expanding the system function, it is necessary to modify the factory class

  • The BeanFactory in Spring uses the simple factory pattern

// 抽象产品
public abstract class Weapon {
    // 所有的武器都可以攻击
    public abstract void attack();
}

// 具体产品
public class Dagger extends Weapon{
    @Override
    public void attack() {
        System.out.println("砍他!!!");
    }
}
public class Fighter extends Weapon{
    @Override
    public void attack() {
        System.out.println("战斗机丢炸弹!!!");
    }
}
public class Tank extends Weapon{
    @Override
    public void attack() {
        System.out.println("坦克开炮!!!");
    }
}

// 工厂类
public class WeaponFactory {
    /**
     * 静态方法: 要获取什么产品? 就看你传什么参数
     * 简单工厂模式中有一个静态方法, 所以被称为: 静态工厂方法模式
     */
    public static Weapon get(String weaponType){
        if("TANK".equals(weaponType)){
            return new Tank();
        } else if("DAGGER".equals(weaponType)){
            return new Dagger();
        } else if("FIGHTER".equals(weaponType)){
            return new Fighter();
        } else {
            throw new RuntimeException("不支持该武器的生产!");
        }
    }
}

// 客户端程序
public class Test {
    public static void main(String[] args) {
        // 需要坦克
        // 对于我客户端来说, 坦克的生产细节, 我不需要关心, 我只需要向工厂索要就行
        // 简单工厂模式达到了什么呢? 职责分离, 客户端不需要关心产品的生产细节
        // 客户端只负责消费, 工厂类负责生产, 一个负责生产, 一个负责消费, 生产者和消费者分离, 者就是简单工厂的作用
        Weapon tank = WeaponFactory.get("TANK");
        tank.attack();
        Weapon fighter = WeaponFactory.get("FIGHTER");
        fighter.attack();
        Weapon dagger = WeaponFactory.get("DAGGER");
        dagger.attack();

        Tank tank1 = new Tank();
        tank1.attack();
    }
}

2.3 Factory method pattern:

  • The factory method pattern not only retains the advantages of the simple factory pattern, but also solves the shortcomings of the simple factory pattern

  • Advantages of factory method pattern:

  • When you expand a product, it conforms to the OCP principle, because only two classes are needed, one class is a specific product class, and the other class is a specific factory class, both of which are added classes, without modifying the previous code, so it conforms to OCP

  • A caller wants to create an object, as long as it knows its name

  • Shield the specific implementation of the product, the caller only cares about the interface of the product

  • Disadvantages of factory method pattern:

  • Every time you add a product, you need to add a concrete class and object implementation factory, which doubles the number of classes in the system

  • To a certain extent, it increases the complexity of the system, and also increases the dependence on the specific classes of the system, which is not a good thing.

  • The roles of the factory method pattern include:

  • Abstract product role Weapon

  • Specific product role Dagger Gun

  • Abstract factory role WeaponFactory

  • Specific factory roles DaggerFactory GunFactory

  • One product one factory

// 抽象产品角色
public abstract class Weapon {
    // 所有的武器都可以攻击
    public abstract void attack();
}

// 具体产品角色:
public class Tank extends Weapon {
    @Override
    public void attack() {
        System.out.println("坦克开炮!!!");
    }
}
public class Fighter extends Weapon {
    @Override
    public void attack() {
        System.out.println("战斗机丢炸弹!!!");
    }
}

// 具体工厂角色:
public class TankFactory extends WeaponFactory{
    @Override
    public Weapon get() {
        return new Tank();
    }
}
public class FighterFactory extends WeaponFactory{
    @Override
    public Weapon get() {
        return new Fighter();
    }
}

// 抽象工厂角色
abstract public class WeaponFactory {

     // 这个方法不是静态的, 是实例方法
     public abstract Weapon get();
}

// 这是客户端程序
public class Test {
    public static void main(String[] args) {
        WeaponFactory weaponFactory = new TankFactory();
        Weapon tank = weaponFactory.get();
        tank.attack();

        WeaponFactory weaponFactory1 = new FighterFactory();
        Weapon fighter = weaponFactory1.get();
        fighter.attack();
    }
}

3. Bean acquisition methods (4 types):

  • Spring provides a variety of instantiation methods for Bean, usually including 4 methods, that is to say, in spring, a variety of solutions are prepared for the creation of Bean objects, the purpose is: more flexible

  • The first method: instantiate through the constructor

// xml
// 直接在spring配置文件中配置类全路径
// Spring会自动的调用该类的无参数构造方法来实例化bean
<bean id="dog" class="com.powernode.bean.Dog"></bean>

// @Test
public void setEmpty(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Dog dog = ctx.getBean("dog", Dog.class);
    System.out.println(dog);
}
  • The second way: instantiate through a simple factory pattern

  • Through the simple factory pattern, you need to tell the spring framework in the spring configuration file, which method of which class to call to get the Bean

  • The factory-method attribute specifies the static method in the factory class , which tells the Spring framework that calling this method can get the Bean

// 类
public class Start {
    public Start() {
        System.out.println("大明星");
    }
}

// 简单工厂模式中的工厂类角色
public class StartFactory {
    // 工厂类中有一个静态方法
    // 简单工厂模式, 又叫做: 静态工厂方法模式
    public static Start get(){
        return new Start();
    }
}

// xml
// Spring提供的实例化方式第二种, 通过简单工厂模式, 你需要在spring配置文件中告诉spring框架, 调用哪个类的哪个方法获取Bean
// factory-method 属性指定的是工厂类当中的静态方法, 也就是告诉Spring框架, 调用这个方法可以获取Bean
<bean id="stars" class="com.powernode.xxxx.StartFactory" factory-method="get"/>
    
// @Test
public void conStars(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Start strs = ctx.getBean("stars", Start.class);
    System.out.println(strs);
}
  • The third way: instantiate through factory-bean

  • Through the factory method mode, through the factory-bean attribute + factory-method attribute to complete together, tell the spring framework, which method of which object to call to obtain the bean

  • The factory-bean attribute tells spring which object to call, and the factory-method tells spring which method to call the object

// 工厂方法模式中的具体产品角色
public class Gun {
    public Gun() {
        System.out.println("开枪!!");
    }
}

// 工厂方法模式中的具体工厂角色
public class GunFactory {
    // 工厂模式中的具体工厂角色中的方法是: 实例方法
    public Gun get(){
        return new Gun();
    }
}

// xml
// Spring提供的实例化方式第三种, 通过工厂方法模式, 通过factory-bean属性+factory-method属性共同完成, 告诉spring框架, 调用哪个对象的哪个方法来获取bean
<bean id="gunFactory" class="com.powernode.xxxx.GunFactory"/>
// factory-bean属性告诉spring调用哪个对象, factory-method告诉spring调用该对象的哪个方法
<bean id="gun" factory-bean="gunFactory" factory-method="get"/>

// @Test
public void conGun(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Gun gun = ctx.getBean("gun", Gun.class);
    System.out.println(gun);
}
  • The fourth way: instantiate through the FactoryBean interface

  • In the third way above, factory-bean is defined by ourselves, and factory-method is also defined by ourselves

  • When the class you write directly implements the FactoryBean interface, the factory-bean does not need to be specified, nor does the factory-method.

  • factory-bean will automatically point to the class that implements the FactoryBean interface, and factory-method will automatically point to the getObject() method

// 普通的bean
public class Person {
    public Person() {
        System.out.println("蚂蚁");
    }
}

// PersonFactory也是一个bean, 只不过这个bean有点特殊, 叫做工厂bean
// 通过工厂Bean这个特殊的Bean可以获取一个普通的Bean
public class PersonFactory implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new Person();
    }

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

    // 这个方法在接口当中默认实现的
    // 默认返回true, 表示单例的
    // 如果想多例, 直接修改为return false即可
    @Override
    public boolean isSingleton() {
        return true;
    }
}

// xml
// 这种方式实际上就是第三种方式的简化, 由于你编写的类实现了BeanFactory接口, 所有不需要手动指定factory-bean factory-method
// 通过FactoryBean这个工厂Bean主要是想对普通Bean进行加工处理
<bean id="person" class="com.powernode.xxxx.PersonFactory"/>
    
// @Test
public void conPerson(){
    ApplicationContext ctx = new ClassPathXmlApplicationContext("set-DI.xml");
    Person person = ctx.getBean("person", Person.class);
    System.out.println(person);
}

4. The difference between BeanFactory and FactoryBean:

  • BeanFactory

  • The top-level interface of the Spring IoC container , BeanFactory is translated as "Bean Factory", in the Spring IoC container, the Bean Factory is responsible for the creation of Bean objects

  • BeanFactory is the factory

  • FactoryBean

  • It is a factory bean, a bean that can assist Spring to instantiate other bean objects

  • In Spring, beans can be divided into two categories:

  1. Plain Bean

  1. Factory Bean (Factory Bean is also a kind of Bean, but this kind of Bean is special, it can assist Spring to instantiate other Bean objects)

5. The difference between ApplicationContext and BeanFactory:

  • Same point:

  • You can get the Spring context object

  • Both are top-level interfaces from Spring

  • difference:

  • Inheritance relationship and functions: ApplicationContext belongs to the subclass of BeanFactory , BeanFactory only has the ability to simply access beans, and ApplicationContext not only has BeanFactory functions, but also includes more functions (internationalization support, resource access, event propagation)

  • Performance: The ApplicationContext loading method is to load the Bean object at one time , so it will be very fast when accessing the Bean object later. When the BeanFactory needs a certain Bean, it loads the Bean object , so it is relatively slow when executing the Bean acquisition.

Guess you like

Origin blog.csdn.net/qq_68993495/article/details/128925987