Several definitions of Java Bean and Spring Bean

Java Bean 和 Spring Bean

Beans are objects.

Whether it is a Java Bean or a Spring Bean, it is for obtaining instantiated objects. Among the differences, the blog in this chapter uses a code case to illustrate.

Java Bean

Java Bean is a Java object. In Java, an object is defined to be newinstantiated.

class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }
}
public class Test {
    
    
    public static void main(String[] args) {
    
    
        User user = new User();
        user.setName("香蕉");
        System.out.println(user.getName());
    }
}

Spring Bean

To test using Spring Bean, you need to introduce Spring dependency files.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.13.RELEASE</version>
</dependency>

XML create bean

Create a User.java class

package cn.linkpower.xml;

public class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

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

In the resourcesCreate the following file spring.xmlfile and configure the specified Bean.

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

	<!--    1、定义bean(根据User中的构造方法生成bean对象)-->
    <bean id="userBean" class="cn.linkpower.xml.User"></bean>
</beans>

Create a test class, add the specified spring.xmlfile to the Spring container, implement object acquisition, set value and call, etc.

package cn.linkpower.xml;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
        //classPathXmlApplicationContext.setConfigLocation("spring.xml");

        User userBean = classPathXmlApplicationContext.getBean("userBean", User.class);
        userBean.setName("香蕉");
        System.out.println(userBean.getName());

		  // 验证Spring的bean是单例!
//        User userBean2 = classPathXmlApplicationContext.getBean("userBean", User.class);
//        userBean2.setName("香蕉2");
//        System.out.println(userBean.getName());
//        System.out.println(userBean2.getName());
//        System.out.println(userBean.getName());
    }
}

@Bean Create Bean

The above operation, according to the bean object specified in the xml configuration, org.springframework.context.support.ClassPathXmlApplicationContextis loaded into the spring container to achieve object generation and reference operations.

At the same time, @Beanthe generation of objects can also be implemented.

package cn.linkpower.beans;

import org.springframework.context.annotation.Bean;

public class UserConfig {
    
    
	/**
     * 采取 @Bean 的方式,构建一个 bean对象;<br/>
     * 相当于 <bean id="getUser" class="cn.linkpower.beans.User" />
     * @return
     */
    @Bean
    public User getUser(){
    
    
        return new User();
    }
}

To use AnnotationConfigApplicationContext, load it into the container.
Test class writing

package cn.linkpower.beans;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        // 构建容器
        //AnnotationConfigApplicationContext annotationConfigApplicationContext = new  AnnotationConfigApplicationContext();
        // 加载、注册配置类
       // annotationConfigApplicationContext.register(UserConfig.class);
        //annotationConfigApplicationContext.refresh();
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(UserConfig.class);
        // 获取对象
        User getUser = annotationConfigApplicationContext.getBean("getUser", User.class);

        getUser.setName("banana");

        System.out.println(getUser.getName());
    }
}

@CompantScan Create Bean

The above two methods both need to configure or write configuration classes to define or construct beans. If there are too many objects, you need to configure more.

In addition, it can also implement class definition operations based on scanning operations.

Write a scan operation tool class (create a class and add annotation operations). Of course, the SpringBoot project defaults to scan the scan startup class directory:

package cn.linkpower.beanScan;

import org.springframework.context.annotation.ComponentScan;

/**
 * @ComponentScan 注解,扫描的是带有 @Component 的类,将其解析加载至spring容器中
 */
@ComponentScan("cn.linkpower.beanScan")
public class UserConfigScan {
    
    
}

The use of @ComponentScanannotations, designated scanning 路径, the carrying @Componentmarked class, Spring loaded onto the vessel, if need be loaded into the class Spring container, you need to add the class specified in the Componentannotation.

package cn.linkpower.beanScan;

import org.springframework.stereotype.Component;

@Component
public class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

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

Write the test class:

package cn.linkpower.beanScan;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
    	// 这里主要是加载带有 @ComponentScan 注解的类,实现扫描 @Component 显示或隐式标注的类
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserConfigScan.class);
        // 默认类名驼峰规范,所以此处从容器获取类,使用user
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
    }
}

It is widely used in Springboot @ComponentScan. Secondly, similar @Serviceand other annotations have @Componentannotations marked.

Programmatic BeanDefinition

Spring bean object in the building, take xml 定义 bean, @Bean 注解, @Compant 注解etc., are all 声明式created bean object.

Spring also supports the 编程式creation of instance objects, as shown below:

Need Spring to construct the instantiated bean class 无注解.

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

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

public class Test {
    
    
    public static void main(String[] args) {
    
    
        // 创建容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 执行一次refresh,否则报错
        applicationContext.refresh();
        // 描述一个bean
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(User.class);

        // 将描述的bean,设置别名称,放入容器中
        applicationContext.registerBeanDefinition("userBeanObj",beanDefinition);

        // 从容器中获取bean
        User userBeanObj = applicationContext.getBean("userBeanObj", User.class);
        System.out.println(userBeanObj);

    }
}

In the Spring source code, whether it is to use @Component, @Beanor xml 配置<bean />, with its underlying implementation still or take BeanDefinitionprogrammatic building.

In addition, BeanDefinitionthere are other attribute parameters available for class settings, such as 单例、多例etc.
Insert picture description here
Insert picture description here

FactoryBean build bean

Create a class that needs to be instantiated using Spring ( 无@Component注解):

package cn.linkpower.factoryBean;

public class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

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

Write a factory class, in order to generate beans:

package cn.linkpower.factoryBean;

import org.springframework.beans.factory.FactoryBean;

public class UserFactory implements FactoryBean {
    
    

    /**
     * 生成对象
     * @return
     * @throws Exception
     */
    public Object getObject() throws Exception {
    
    

        return new User();
    }

    /**
     * 对象的类型
     * @return
     */
    public Class<?> getObjectType() {
    
    
        return User.class;
    }
}

Write the test class:

package cn.linkpower.factoryBean;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        // 1、构建容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.refresh();
        // 2、定义bean的修饰类
        AbstractBeanDefinition abstractBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        // 添加一个类进去
        abstractBeanDefinition.setBeanClass(UserFactory.class);
        // 3、将已修饰的类放入容器中
        applicationContext.registerBeanDefinition("userFactoryTest",abstractBeanDefinition);
        //4、获取类
        User user = applicationContext.getBean("userFactoryTest",User.class);
        System.out.println(user);
        
        
        // 这个是报错的!
        //System.out.println(applicationContext.getBean("userFactoryTest",UserFactory.class));
        
        // 如果想获取 UserFactory 对象,则需要 名称写为  &userFactoryTest
        //System.out.println(applicationContext.getBean("&userFactoryTest",UserFactory.class));
    }
}

[注意:]

Using org.springframework.beans.factory.FactoryBeanmodified beans, in fact, the spring container will generate two bean objects.
userFactoryTest—>User object bean
&userFactoryTest—>UserFactory class object bean

Use org.springframework.beans.factory.FactoryBeanthe getObject()indirect definition of a bean.

Supplier defines the bean

In the Spring framework, there is an operation of using Supplier to construct a bean. When the bean is initialized, a class initial data can be generated through the Supplier class. The case information is as follows:

package cn.linkpower.supplier;

public class User {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

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

New test class:

package cn.linkpower.supplier;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.function.Supplier;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.refresh();

        // 通过这种方式 注册bean
        //applicationContext.registerBean(User.class);

        applicationContext.registerBean(User.class, new Supplier<User>() {
    
    
            public User get() {
    
    
                User user = new User();
                user.setName("banana");
                return user;
            }
        });

        User user = applicationContext.getBean("user", User.class);
        System.out.println(user.getName());

    }
}

Insert picture description here

Code reference

github test code address

Guess you like

Origin blog.csdn.net/qq_38322527/article/details/113946325