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

作者:丶_62f3 时间:2022-05-23 03:32:14 

一:对象,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,很多情况下底层其实用的都是一样的东西,只是提供了不同的使用方式,具体可以通过源码查看。

来源:https://www.jianshu.com/p/2e6e07e59599

标签:JavaBean,SpringBean
0
投稿

猜你喜欢

  • Java对象不使用时赋值null的意义详解

    2023-11-25 01:46:20
  • IDEA的Swing可视化插件JFormDesigner详解

    2023-09-23 08:02:54
  • SpringBoot配置Email发送功能实例

    2022-03-07 20:52:20
  • 解决idea web 配置相对路径问题

    2022-01-12 06:48:40
  • Servlet+JDBC实现登陆功能的小例子(带验证码)

    2021-05-29 03:04:25
  • SpringDataJPA在Entity中常用的注解介绍

    2023-11-27 09:40:36
  • C#接口INotifyPropertyChanged使用方法

    2021-11-22 13:33:53
  • kill命令在Java应用中使用的注意事项小结

    2023-11-11 13:01:55
  • 快速了解hibernate配置文件与映射文件

    2023-11-04 23:02:26
  • java批量修改文件后缀名方法总结

    2022-03-15 15:46:04
  • 解析JavaSe的内部类

    2022-08-14 18:19:33
  • 深入讲解Java Maven配置

    2022-07-01 05:09:21
  • SpringBoot依赖管理的源码解析

    2022-10-29 23:37:14
  • spring如何动态指定具体实现类

    2022-04-13 07:52:21
  • spring boot基于Java的容器配置讲解

    2023-11-09 05:24:54
  • Java中Controller、Service、Dao/Mapper层的区别与用法

    2022-09-12 15:14:03
  • maven引入本地jar包运行报错java.lang.NoClassDefFoundError解决

    2022-10-15 01:42:24
  • SpringBoot 创建web项目并部署到外部Tomcat

    2023-09-15 18:25:04
  • Java面试必备八股文整理

    2023-11-29 12:03:50
  • java实现马踏棋盘的算法

    2023-11-29 17:00:29
  • asp之家 软件编程 m.aspxhome.com