欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java Bean 和 Spring Bean 的几种定义

程序员文章站 2022-06-28 16:30:34
文章目录Java Bean 和 Spring BeanJava BeanSpring BeanXML创建bean@Bean创建Bean@CompantScan创建Bean编程式BeanDefinitionJava Bean 和 Spring BeanBean 就是对象。不管是 Java Bean 还是 Spring Bean,都是为了获取实例化对象。其中的区别,本章博客采取代码案例说明。Java BeanJava Bean 即 Java 对象,在Java 中,定义一个对象采取实例话操作。clas...

Java Bean 和 Spring Bean

Bean 就是对象。

不管是 Java Bean 还是 Spring Bean,都是为了获取实例化对象。其中的区别,本章博客采取代码案例说明。

Java Bean

Java Bean 即 Java 对象,在Java 中,定义一个对象采取new实例化操作。

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

测试使用 Spring Bean,则需要引入Spring依赖文件。

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

XML创建bean

创建一个User.java类

package cn.linkpower.xml;

public class User {
    private String name;

    public String getName() {
        return name;
    }

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

resources文件下创建spring.xml文件,并配置指定的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>

创建测试类,将指定的spring.xml文件加入至Spring容器中,实现对象的获取,设置值和调用等。

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创建Bean

上面的操作,根据在xml中定义配置指定的bean对象,采取org.springframework.context.support.ClassPathXmlApplicationContext将其加载至spring容器中,达到对象的生成和引用操作。

同时,也可以采取@Bean实现对象的生成。

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

使用AnnotationConfigApplicationContext,将其加载至容器中。
测试类编写

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创建Bean

上述的两种方式,都需要配置或者编写配置类的方式,定义或构建bean。如果对象过多,则需要配置的就较多。

除此之外,还能根据扫描操作实现类的定义操作。

编写扫描操作工具类(创建一个类,添加注解操作即可),当然,SpringBoot项目默认扫扫描启动类下目录:

package cn.linkpower.beanScan;

import org.springframework.context.annotation.ComponentScan;

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

由于使用@ComponentScan注解,是扫描指定路径下,携带有@Component标注的类,将其加载至Spring容器中,所以如果需要将类加载至Spring容器中,则需要在指定的类上添加Component注解。

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

编写测试类:

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

在Springboot中就广泛使用到@ComponentScan。其次,类似@Service等注解中也有@Component的注解标注。

编程式BeanDefinition

在Spring构建bean对象时,采取xml 定义 bean@Bean 注解@Compant 注解等方式,都属于声明式创建bean对象。

Spring也支持编程式创建实例对象,如下所示:

需要Spring构建实例化bean的类上无注解

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

    }
}

在 Spring 源码中,不管是使用@Component@Bean还是xml 配置<bean />等,其底层的实现依旧还是采取的BeanDefinition进行编程式构建。

除此之外,在BeanDefinition中,还有其他属性参数可供类的设置,如单例、多例等。
Java Bean 和 Spring Bean 的几种定义
Java Bean 和 Spring Bean 的几种定义

FactoryBean 构建bean

创建一个需要使用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;
    }
}

编写一个工厂类,为了生成bean:

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

编写测试类:

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

[注意:]

使用org.springframework.beans.factory.FactoryBean修饰产生的bean,其实spring容器会将其生成两个bean对象。
userFactoryTest—> User 对象bean
&userFactoryTest—>UserFactory 类的对象bean

使用 org.springframework.beans.factory.FactoryBeangetObject()间接定义了一个bean。

Supplier 定义bean

在Spring框架中,存在使用Supplier构建bean的操作,在初始化生成bean时,可以通过Supplier类生成一个类初始的数据。其案例信息如下所示:

package cn.linkpower.supplier;

public class User {
    private String name;

    public String getName() {
        return name;
    }

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

新建测试类:

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());

    }
}

Java Bean 和 Spring Bean 的几种定义

代码参考

github 测试代码地址

本文地址:https://blog.csdn.net/qq_38322527/article/details/113946325

相关标签: Spring框架相关