JavaBean和SpringBean的區(qū)別及創(chuàng)建SpringBean方式
一:對象,JavaBean,SpringBean的區(qū)別
1.什么是JavaBean
javaBean要求所有屬性為私有,該類必須有一個(gè)公共無參構(gòu)造函數(shù),private屬性必須提供公共的Getter setter給外部訪問
/**
* @author yzh
* @date 2021/4/29 8:42
**/
public class User {
//javaBean要求所有屬性為私有,該類必須有一個(gè)公共無參構(gòu)造函數(shù),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的區(qū)別
- 用處不同:傳統(tǒng)javabean更多地作為值傳遞參數(shù),而spring中的bean用處幾乎無處不在,任何組件都可以被稱為bean
- 寫法不同:傳統(tǒng)javabean作為值對象,要求每個(gè)屬性都提供getter和setter方法;但spring中的bean只需為接受設(shè)值注入的屬性提供setter方法
生命周期不同:傳統(tǒng)javabean作為值對象傳遞,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行為
二:如何定義一個(gè)SpringBean
準(zhǔn)備工作:引入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,所有我們現(xiàn)在resources目錄下新建一個(gè)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">
<!-- 使用設(shè)值注入方式裝配實(shí)例 -->
<bean id="user1" class="org.example.bean.User">
<property name="name" value="zhangsan" />
</bean>
<!-- 使用構(gòu)造方法裝配實(shí)例 -->
<!--使用構(gòu)造方法裝配需要在相應(yīng)類提供構(gòu)造函數(shù)-->
<bean id="user2" class="org.example.bean.User">
<constructor-arg index="0" value="lisi" />
</bean>
</beans>
同時(shí)相應(yīng)對象重寫toString方法,便于更好觀察user1和user2
package org.example.bean;
/**
* @author yzh
* @date 2021/4/29 8:42
**/
public class User {
//javaBean要求所有屬性為私有,該類必須有一個(gè)公共無參構(gòu)造函數(shù),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 + '\'' +
'}';
}
}
運(yùn)行測試類
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);
}
}
運(yùn)行結(jié)果如下
User{name='zhangsan'}
User{name='lisi'}
2.通過AnnotationConfigApplicationContext底層
也是通過BeanDefinition實(shí)現(xiàn)
*@Bean@Component@Service@Controller都可以;一般@Service用于Service層,@Controller用于Controller層,此處以@Bean為例
新建一個(gè)Config類,并給User打上@Bean標(biāo)簽
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);
}
}
運(yùn)行結(jié)果
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();
//定義一個(gè)Bean
beanDefinition.setBeanClass(User.class);
//把生成的Bean注冊到容器中
annotationConfigApplicationContext.refresh();
annotationConfigApplicationContext.registerBeanDefinition("userTest",beanDefinition);
User userTest = annotationConfigApplicationContext.getBean("userTest", User.class);
System.out.println(userTest);
}
}
運(yùn)行結(jié)果
User{name='null'}
4.通過FactoryBean
4.1通過FactoryBean與注解方式
首先新建一個(gè)Person類
package org.example.bean;
import org.springframework.stereotype.Component;
/**
* @author yzh
* @date 2021/4/29 10:00
**/
public class Person {
}
然后新建一個(gè)PersonFactoryBean類,并實(shí)現(xiàn)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;
}
}
其次添加一個(gè)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);
}
}
運(yùn)行結(jié)果
org.example.bean.Person@28ac3dc3
4.2通過Factory和BeanDefinition
1.同4.1一樣新建一個(gè)Person類
2.同4.1一樣新建一個(gè)PersonFactoryBean類,實(shí)現(xiàn)FactoryBean接口,但是不打注解
3.通過BeanDefinition獲取對象
此處和注解生成的差別在于通過BeanDefinition注冊的會(huì)生成兩個(gè)Bean對象,一個(gè)是person對應(yīng)的類型是Person,另一個(gè)是&person對應(yīng)的類型是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();
////定義一個(gè)Bean
beanDefinition.setBeanClass(PersonFactoryBean.class);
//把生成的Bean注冊到容器中
//annotationConfigApplicationContext.refresh();
//此處會(huì)生成2個(gè)Bean對象 第一個(gè)對象為&person對應(yīng)的類型的PersonFactoryBean 第二個(gè)對象為person對應(yīng)的類型為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);
}
}
運(yùn)行結(jié)果如下
org.example.bean.PersonFactoryBean@3aeaafa6
org.example.bean.Person@76a3e297
注
FactoryBean接口提供三個(gè)方法,但是我們重寫了兩個(gè)方法,這是因?yàn)榱硗庖粋€(gè)方法是默認(rèn)實(shí)現(xiàn)了的
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();
//默認(rèn)實(shí)現(xiàn)方法,是否是單例
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,很多情況下底層其實(shí)用的都是一樣的東西,只是提供了不同的使用方式,具體可以通過源碼查看。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot基于IDEA環(huán)境熱加載與熱部署教程
這篇文章主要為大家介紹了springboot在IDEA環(huán)境下的熱加載與熱部署教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
Java打包之后讀取Resources下的文件失效原因及解決方法
這篇文章主要給大家介紹了Java打包之后讀取Resources下的文件失效的問題分析和解決方法,文中通過代碼示例和圖文結(jié)合給大家講解非常詳細(xì),需要的朋友可以參考下2023-12-12
JAVA HashSet和TreeSet 保證存入元素不會(huì)重復(fù)的操作
這篇文章主要介紹了JAVA HashSet和TreeSet 保證存入元素不會(huì)重復(fù)的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
解決Lombok使用@Builder無法build父類屬性的問題
這篇文章主要介紹了解決Lombok使用@Builder無法build父類屬性的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
Mybatis-plus通過添加攔截器實(shí)現(xiàn)簡單數(shù)據(jù)權(quán)限
系統(tǒng)需要根據(jù)用戶所屬的公司,來做一下數(shù)據(jù)權(quán)限控制,具體一點(diǎn),就是通過表中的company_id進(jìn)行權(quán)限控制,項(xiàng)目使用的是mybatis-plus,所以通過添加攔截器的方式,修改查詢sql,實(shí)現(xiàn)數(shù)據(jù)權(quán)限,本文就通過代碼給大家詳細(xì)的講解一下,需要的朋友可以參考下2023-08-08
java一個(gè)數(shù)據(jù)整理的方法代碼實(shí)例
這篇文章主要介紹了java一個(gè)數(shù)據(jù)整理的方法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09

