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