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


猜你喜欢
- Java 8新特性方法引用对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容!Java 8的方法引用定义
- 最近项目里涉及到自定义View的东西还是挺多的,所以打算在自定义View上多花点时间,也顺便分享给大家。先总结下自定义View的步骤:1、自
- 实现多线程的方式:实现多线程的方式有多种,这里只列举两种常用的,而第一种继承Thread的方式无法实现多窗口卖票。一,继承Thread方式:
- java多线程-同步块Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java 同步块用来避免竞争。
- 前言在《C# wpf Canvas中实现控件动态调整大小》中我们实现了Canvas中的控件动态调整大小,由于Grid也是可层叠布局,在Gri
- 静态方法可以不用创建对象就调用,非静态方法必须有了对象的实例才能调用。因此想在静态方法中直接引用非静态方法是不可能的,因为不知道调用哪个对象
- 话说2016年的直播比较火,2017年短视频又火了。但对于开发者来说隐藏在这背后的技术才是我们所关心的,毕竟我们是靠技术吃饭的。现在在安卓中
- 现象:安装失败,具体信息:Installation did not succeed.The application could not be
- 一、线程池简介线程池的使用主要是解决两个问题:①当执行大量异步任务的时候线程池能够提供更好的性能,在不使用线程池时候,每当需要执行异步任务的
- 1.先下载NuGet包(ZXing.Net)2.新建控制器及编写后台代码using System;using System.Collecti
- 在客户机和服务器之间建立单一的双向连接,这就意味着客户只需要发送一个请求到服务端,那么服务端则会进行处理,处理好后则将其返回给客户端,客户端
- 前言继上次skywalking出故障《解析Arthas协助排查线上skywalking不可用问题》不到一个月,线上skywalking又出毛
- TubeMQ总体介绍TubeMQ是腾讯大数据在2013年开始研发的分布式消息中间件系统(MQ),专注服务大数据场景下海量数据的高性能存储和传
- 一,我们使用两个域名互相访问的时候会提示跨域,原因在哪里呢?如下图跨域,我们探究下是什么原因导致浏览器报这个错呢?二,我们研究下看看请求是否
- AutoCompleteTextView是实现动态匹配输入内容的一种输入框(EditText),如输入“and”时,会提示“Android”
- 异常处理是每个项目中都绕不开的话题,那么如何优雅的处理异常,是本文的话题。本文将结合SpringBoot框架一起和大家探讨下。要思考的问题在
- 本文实例为大家分享了Android自定义View实现标签流效果的具体代码,供大家参考,具体内容如下一、概述Android自定义View实现标
- 本文使用Matrix实现Android实现图片缩放与旋转。示例代码如下:package com.android.matrix;import
- 有很多应用场景,用到了接口动态实现,下面举几个典型的应用:1、mybatis / jpa 等orm框架,可以在接口上加注解进行开发,不需要编
- AsnyncLocal与ThreadLocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在:AsyncLocal