JavaBean和SpringBean的区别及创建SpringBean方式

 更新时间:2021年10月13日 09:51:31   作者:丶_62f3  
这篇文章主要介绍了JavaBean和SpringBean的区别及创建SpringBean方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

一:对象,JavaBean,SpringBean的区别

1.什么是JavaBean

javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问

/**
 * @author yzh
 * @date 2021/4/29 8:42
 **/
public class User {
    //javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

2.什么是SpringBean

SpringBean是受Spring管理的对象,所有能受Spring管理的对象都可以是SpringBean

3.SpringBean和JAVABean的区别

  • 用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处不在,任何组件都可以被称为bean
  • 写法不同:传统javabean作为值对象,要求每个属性都提供getter和setter方法;但spring中的bean只需为接受设值注入的属性提供setter方法

生命周期不同:传统javabean作为值对象传递,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行为

二:如何定义一个SpringBean

准备工作:引入Spring依赖包

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.14.RELEASE</version>
</dependency>

1.通过ClassPathXmlApplicationContext

通过ClassPathXmlApplicationContext需要指定configLocation,所有我们现在resources目录下新建一个Spring.xml文件

<?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-3.2.xsd">
    <!-- 使用设值注入方式装配实例 -->
    <bean id="user1" class="org.example.bean.User">
        <property name="name" value="zhangsan" />
    </bean>
    <!-- 使用构造方法装配实例 -->
    <!--使用构造方法装配需要在相应类提供构造函数-->
    <bean id="user2" class="org.example.bean.User">
        <constructor-arg index="0" value="lisi" />
    </bean>
</beans>

同时相应对象重写toString方法,便于更好观察user1和user2

package org.example.bean;
/**
 * @author yzh
 * @date 2021/4/29 8:42
 **/
public class User {
    //javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public User(String name) {
        this.name = name;
    }
    public User() {
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

运行测试类

package org.example.bean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
        classPathXmlApplicationContext.setConfigLocation("Spring.xml");
        classPathXmlApplicationContext.refresh();
        User user1 = classPathXmlApplicationContext.getBean("user1",User.class);
        System.out.println(user1);
        User user2 = classPathXmlApplicationContext.getBean("user2", User.class);
        System.out.println(user2);
    }
}

运行结果如下

User{name='zhangsan'}

User{name='lisi'}

2.通过AnnotationConfigApplicationContext底层

也是通过BeanDefinition实现

*@Bean@Component@Service@Controller都可以;一般@Service用于Service层,@Controller用于Controller层,此处以@Bean为例

新建一个Config类,并给User打上@Bean标签

package org.example.bean;
import org.springframework.context.annotation.Bean;
/**
 * @author yzh
 * @date 2021/4/29 9:20
 **/
public class Config {
    @Bean
    public User user(){
        return  new User();
    }
}

通过AnnotationConfigApplicationContext获取bean,并打印bean对象

package org.example.bean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(Config.class);
        annotationConfigApplicationContext.refresh();
        User user = annotationConfigApplicationContext.getBean("user",User.class);
        System.out.println(user);
    }
}

运行结果

User{name='null'}

3.通过BeanDefinition

package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
  
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
 
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        //定义一个Bean
        beanDefinition.setBeanClass(User.class);
        //把生成的Bean注册到容器中
        annotationConfigApplicationContext.refresh();
        annotationConfigApplicationContext.registerBeanDefinition("userTest",beanDefinition);
        User userTest = annotationConfigApplicationContext.getBean("userTest", User.class);
        System.out.println(userTest);
    }
}

运行结果

User{name='null'}

4.通过FactoryBean

4.1通过FactoryBean与注解方式

首先新建一个Person类

package org.example.bean;
import org.springframework.stereotype.Component;
/**
 * @author yzh
 * @date 2021/4/29 10:00
 **/
public class Person {
}

然后新建一个PersonFactoryBean类,并实现FactoryBean接口,重写其方法,为其打上@component注解, 此处和在Person类上打注解是同一效果

package org.example.bean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
 * @author yzh
 * @date 2021/4/29 10:01
 **/
@Component("person")
public class PersonFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new Person();
    }
    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }
}

其次添加一个Config类打上@ComponentScan("org.example.bean"),目的是为了扫描包下的注解

package org.example.bean;
import org.springframework.context.annotation.ComponentScan;
/**
 * @author yzh
 * @date 2021/4/29 9:20
 **/
@ComponentScan("org.example.bean")
public class Config {
}

最后通过AnnotationConfigApplicationContext获取Bean

package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
         //Config类为包扫描配置类
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
        Person person = annotationConfigApplicationContext.getBean("person", Person.class);
        System.out.println(person);
    }
}

运行结果

org.example.bean.Person@28ac3dc3

4.2通过Factory和BeanDefinition

1.同4.1一样新建一个Person类

2.同4.1一样新建一个PersonFactoryBean类,实现FactoryBean接口,但是不打注解

3.通过BeanDefinition获取对象

此处和注解生成的差别在于通过BeanDefinition注册的会生成两个Bean对象,一个是person对应的类型是Person,另一个是&person对应的类型是PersonFactoryBean,通过下面代码的getBean方法可以看出来!!

package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
  
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
    
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        ////定义一个Bean
        beanDefinition.setBeanClass(PersonFactoryBean.class);
        //把生成的Bean注册到容器中
        //annotationConfigApplicationContext.refresh();
        //此处会生成2个Bean对象 第一个对象为&person对应的类型的PersonFactoryBean 第二个对象为person对应的类型为Person;
        annotationConfigApplicationContext.registerBeanDefinition("person",beanDefinition);
        PersonFactoryBean personFactoryBean = annotationConfigApplicationContext.getBean("&person", PersonFactoryBean.class);
        System.out.println(personFactoryBean);
        Person person = annotationConfigApplicationContext.getBean("person", Person.class);
        System.out.println(person);
    }
}

运行结果如下

org.example.bean.PersonFactoryBean@3aeaafa6

org.example.bean.Person@76a3e297

FactoryBean接口提供三个方法,但是我们重写了两个方法,这是因为另外一个方法是默认实现了的

FactoryBean接口方法如下:

package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
public interface FactoryBean<T> {
    
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    @Nullable
    T getObject() throws Exception;
    
    @Nullable
    Class<?> getObjectType();
    //默认实现方法,是否是单例
    default boolean isSingleton() {
        return true;
    }
}

5.通过Supplier

package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.function.Supplier;
/**
 * @author yzh
 * @date 2021/4/29 8:45
 **/
public class Main {
    public static void main(String[] args) {
     
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.refresh();
        annotationConfigApplicationContext.registerBean(User.class, new Supplier<User>() {
            @Override
            public User get() {
                User user = new User();
                user.setName("123");
                return user;
            }
        });
        User user = annotationConfigApplicationContext.getBean("user", User.class);
        System.out.println(user);
    }
}

bean的注入方式本文只是提供了多种api,很多情况下底层其实用的都是一样的东西,只是提供了不同的使用方式,具体可以通过源码查看。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 基于Java写minio客户端实现上传下载文件

    基于Java写minio客户端实现上传下载文件

    这篇文章主要介绍了基于Java写minio客户端实现上传下载文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 使用Feign动态设置header和原理分析

    使用Feign动态设置header和原理分析

    这篇文章主要介绍了使用Feign动态设置header和原理分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java 全方位讲解面向对象特点与使用

    Java 全方位讲解面向对象特点与使用

    面向对象开发方法将面向对象的思想应用于软件开发过程中,指导开发活动,是建立在“对象”概念基础上的方法学,简称OO( Object-Oriented)方法
    2022-04-04
  • IDEA 如何导入别人的javaweb项目进行部署

    IDEA 如何导入别人的javaweb项目进行部署

    这篇文章主要介绍了IDEA 如何导入别人的javaweb项目进行部署,本文给大家分享我的详细部署过程及遇到问题解决方法,需要的朋友可以参考下
    2023-03-03
  • 详解Mybatis中的select方法

    详解Mybatis中的select方法

    这篇文章主要介绍了Mybatis的select方法,通过代码给大家详细介绍了selectByExample方法,selectById方法,需要的朋友可以参考下
    2018-07-07
  • java中brew安装rabbitmq以及简单实例

    java中brew安装rabbitmq以及简单实例

    RabbitMQ是基于AMQP协议,由Erlang语言开发的开源消息队列系统,广泛应用于分布式系统中,用于应用程序间的消息传递,它支持多种交换机类型,如直连交换机、扇形交换机和主题交换机等,能够满足不同的消息路由需求
    2024-10-10
  • Spring中如何使用@Value注解实现给Bean属性赋值

    Spring中如何使用@Value注解实现给Bean属性赋值

    这篇文章主要介绍了Spring中如何使用@Value注解实现给Bean属性赋值的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 基于Java的度分秒坐标转纯经纬度坐标的漂亮国基地信息管理的方法

    基于Java的度分秒坐标转纯经纬度坐标的漂亮国基地信息管理的方法

    本文以java语言为例,详细介绍如何管理漂亮国的基地信息,为下一步全球的空间可视化打下坚实的基础,首先介绍如何对数据进行去重处理,然后介绍在java当中如何进行度分秒位置的转换,最后结合实现原型进行详细的说明,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • Java如何利用Mybatis进行数据权限控制详解

    Java如何利用Mybatis进行数据权限控制详解

    这篇文章主要介绍了Java如何利用Mybatis进行数据权限控制详解,数据权限控制最终的效果是会要求在同一个数据请求方法中,根据不同的权限返回不同的数据集,而且无需并且不能由研发编码控制。,需要的朋友可以参考下
    2019-06-06
  • Java实现XML与JSON秒级转换示例详解

    Java实现XML与JSON秒级转换示例详解

    这篇文章主要为大家介绍了Java实现XML与JSON秒级转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论