国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

用py做網(wǎng)站b2b網(wǎng)站源碼

用py做網(wǎng)站,b2b網(wǎng)站源碼,手機網(wǎng)站建好怎么發(fā)布,做英語翻譯兼職的網(wǎng)站&#x1f3e1;Java碼農(nóng)探花&#xff1a; &#x1f525; 推薦專欄&#xff1a;<springboot學習> &#x1f6f8;學無止境&#xff0c;不驕不躁&#xff0c;知行合一 文章目錄 前言一、IoC容器的簡介BeanFactory接口源碼二、Bean裝配掃描裝配探索啟動類條件裝配自定義Bean總…

🏡Java碼農(nóng)探花

?🔥 推薦專欄:<springboot學習>

🛸學無止境,不驕不躁,知行合一


文章目錄
  • 前言
  • 一、IoC容器的簡介
  • BeanFactory接口源碼
  • 二、Bean裝配
  • 掃描裝配
  • 探索啟動類
  • 條件裝配
  • 自定義Bean
  • 總結(jié)


前言

IoC((Inversion of Control,控制反轉(zhuǎn))容器是 Spring 的核心,可以說 Spring 是一種基于 IoC容器編程的框架。因為Spring Boot 是基于注解的開發(fā) Spring IoC, 所以我們就從全注解的方式來講訴Bean裝配。


一、IoC容器的簡介

Spring IoC?容器是一個管理 Bean 的容器,在?Spring?的定義中,它要求所有的 IoC 容器都需要實現(xiàn)接口?BeanFactory,它是一個頂級容器接口。 我們從源碼講訴。

BeanFactory接口源碼

package org.springframework.beans.factory;import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;public interface BeanFactory {// 前綴String FACTORY_BEAN_PREFIX = "&";// 多個getBean方法Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);// 是否包含Beanboolean containsBean(String name);//是否單例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否原型boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否類型匹配boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;// 獲取Bean的類型@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;// 獲取Bean的別名@NullableClass<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;String[] getAliases(String name);
}

分析:

  • 上訴源碼中加入了中文注釋,通過它們就可以理解這些方法的含義。
  • 這里值得注意的是接口中的幾個方法:
    • 首先我們看到了多個getBean 方法,這也是IoC 容器最重要的方法之一, 它的意義是從IoC 容器中獲取Bean而從多個getBean方法中可以看到有按類型(bytype)獲取Bean?的,也有按名稱(by name)獲取 Bean?的,這就意味著在 Spring IoC 容器中,允許我們按類型或者名稱獲取 Bean。這對理解后面將講到的Spring 的依賴注入(Dependency Injection, DI) 是十分重要的。
    • isSingleton 方法則判斷 Bean 是否在 Spring IoC 中為單例。這里需要記住的是在 Spring IoC 容器中,默認的情況下, Bean 都是以單例存在的,也就是使用 getBean 方法返回的都是同一個對象。與isSingleton 方法相反的是?isPrototype 方法,如果它返回的是 true,那么當我們使用 getBean 方法獲取Bean 的時候, Spring IoC 容器就會創(chuàng)建一個新的 Bean?返回給調(diào)用者。

由于BeanFactory 的功能還不夠強大,因此 Spring 在 BeanFactory 的基礎上, 還設計了一個更為高級的接口?ApplicationContext。 它是 BeanFactory 的子接口之一, 在 Spring 的體系中?BeanFactory?和ApplicationContext?是最為重要的接口設計,在現(xiàn)實中我們使用的大部分 Spring IoC 容器是ApplicationContext 接口的實現(xiàn)類。

在這里插入圖片描述

  • 在圖中可以看到,?ApplicationContext 接口通過繼承上級接口,進而繼承 BeanFactory 接口, 但是在BeanFactory 的基礎上,擴展了消息國際化接口(MessageSource)、環(huán)境可配置接口 (EnvironmentCapable)、應用事件發(fā)布接口(ApplicationEventPublish巳r) 和資源模式解析接口(ResourcePatternResolver),所以它的功能會更為強大
  • 在Spring Boot 當中我們主要是通過注解來裝配Bean到 Spring IoC 容器中,為了貼近 SpringBoot 的需要, 這里不再介紹與 XML 相關的 IoC 容器,而主要介紹一個基于注解的 IoC 容器,它就是AnnotationConfigApplicationContext,從名稱就可以看出它是一個基于注解的 IoC 容器。 之所以研究它, 是因為Spring Boot 裝配和獲取 Bean 的方法與它如出一轍。

例:創(chuàng)建一個User類,然后使用AnnotationConfigApplicationContext構(gòu)建IoC容器

public class User {private Long id; private String userName; 
/**setter and getter **/ 
}

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Con f工guration ;
import com.springboot.chapter3.po] o.User;
@Configuration 
public class AppConfig { @Bean(name =”user” } public User ini tUser () { User user= new User (); user. set Id (1L) ; user.setUserName (”aa”); return user;}
}

@Configuration?代表這是一個 Java 配置文件, Spring 的容器會根據(jù)它來生成IoC 容器去裝配Bean;@Bean 代表將 initUser 方法返回的 POJO 裝配到 IoC 容器中,而其屬性name 定義這個 Bean 的名稱如果沒有配置它,則將方法名稱“initUser”作為 Bean 的名稱保存到Spring IoC 容器中。

import org.apache. log4j .Logger; 
import org. springframework.context.ApplicationContext; 
import org. springframework.context annotation.AnnotationConfigApplicat工onContext;
import com.springboot.chapter3.po] o .User;
public class IoCTest { private static Logger log= Logger.getLogger(IoCTest.class); publ工c static 飛roid main (String [] args) { ApplicationContext ctx = new AnnotationConfigAppl豐cationContext(AppConfig. class);User user= ctx.getBean(User.class); }
}

代碼中將Java 配置文件 AppConfig 傳遞給 AnnotationConfigApplicationContext 的構(gòu)造方法,這樣它就能夠讀取配置了。然后將配置里面的Bean裝配到IoC容器中,于是可以使用 getBean方法獲取對應的POJO。

二、Bean裝配

掃描裝配

上訴講訴的User對象裝配就是使用@Bean裝配。但是如果一個個的 Bean 使用注解@Bean 注入 Spring loC 容器中,那將是一件很麻煩的事情。好在Spring 還允許我們進行掃描裝配?Bean 到 loC 容器中,對于掃描裝配而言使用的注解是@Component和@ComponentScan。@Component 是標明l哪個類被掃描進入 Spring IoC 容器,而ComponentScan則是標明采用何種策略去掃描裝配Bean。

@Component(”user") 
public class User { @Value("1") private Long id; @Value("aa"} private String userName; 
/**setter and getter **/ 
}

這里的注解@Component表明這個類將被SpringIoC 容器掃描裝配,其中配置的“user"則是作為Bean 的名稱,當然你也可以不配置這個字符串,那么IoC容器就會把類名第一個字母作為小寫其他不變作為Bean 名稱放入到IoC 容器中注解@Value則是指定具體的值,使得Spring IoC給予對應的屬性注入對應的值。為了讓SpringIoC 容器裝配這個類, 需要改造類AppConfig:

import org.springframework.context.annotat工on.ComponentScan;
import org.springframework.context.annotation Configuration; 
@Configuration 
@ComponentScan 
public class AppConfig {
}

這里加入了@ComponentScan,意味著它會進行掃描,但是它只會掃描類AppConfig所在的當前包和其子包。也就是@ComponentScan默認掃描當前類所在包及其子包。 所以User類的位置要注意。

測試:

Applicat工onContext ctx = new AnnotationConfigApplicationContext{AppConfig.class) ;
User user= ctx.getBean(User.class); 
log. info(user.getid());

為了更加合理,@ComponentScan還允許我們自定義掃描的包,我們看一下源碼:

package org.springframework.context.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//在一個類中可重復定義
@Repeatable(ComponentScans.class)
public @interface ComponentScan {// 定義掃描的包@AliasFor("basePackages")String[] value() default {};//定義掃描的包@AliasFor("value")String[] basePackages() default {};//定義掃描的類Class<?>[] basePackageClasses() default {};//Bean name生成器Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;//作用域解析器Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;//作用域代理模式ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;//資源匹配模式String resourcePattern() default "**/*.class";//是否啟用默認的過濾器boolean useDefaultFilters() default true;//當滿足過濾器的條件時掃描Filter[] includeFilters() default {};//當不滿足過濾器的條件時掃描Filter[] excludeFilters() default {};//是否延遲初始化boolean lazyInit() default false;//定義過濾器@Retention(RetentionPolicy.RUNTIME)@Target({})public @interface Filter {//過濾器類型,可以按注解類型或者正則式等過濾FilterType type() default FilterType.ANNOTATION;//定義過濾的類@AliasFor("classes")Class<?>[] value() default {};@AliasFor("value")Class<?>[] classes() default {};//匹配方式String[] pattern() default {};}
}

分析:

  • 首先可以通過配置項basePackages定義掃描的包名,在沒有定義的情況下,它只會掃描當前包和其子包下的路徑:還可以通過basePackageClasses 定義掃描的類;
  • 其中還有 includeFilters 和 excludeFilters,?includeFilters 是定義滿足過濾器(Filter)條件的 Bean 才去掃描,?excludeFilters 則是排除過濾器條件的 Bean,它們都需要通過一個注解@Filter 去定義,它有一個type 類型,這里可以定義為注解或者正則式等類型。 classes定義注解類, pattern 定義正則式類

所以得出三個掃描路徑表示:

@ComponentScan ("com.springboot.example.* ")
@ComponentScan(basePackages = {"com.springboot.example.pojo"})
@ComponentScan(basePackageClasses = {User.class} ) 

以及排除掃描包或類,讓其不被裝配:

//掃描example下所有包除了@Service裝配的類
//這樣,由于加入了 excludeFilters 的配置,使標注了@Service 的類將不被 IoC 容器掃描注入,這樣就可以把它類排除到 Spring IoC容器中了。
@ComponentScan(basePackages = {"com.dragon.restart"},excludeFilters = {@ComponentScan.Filter(classes = Service.class)})
探索啟動類

事實上,之前在 Spring Boot 的注解@SpringBootApplication 也注入了@ComponentScan,這里不妨探索其源碼:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
//自定義排除的掃描類
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {//通過類型排除自動配置@AliasFor(annotation = EnableAutoConfiguration.class)Class<?>[] exclude() default {};//通過名稱排除自動配置類@AliasFor(annotation = EnableAutoConfiguration.class)String[] excludeName() default {};//定義掃描包@AliasFor(annotation = ComponentScan.class,attribute = "basePackages")String[] scanBasePackages() default {};//定義被掃描的類@AliasFor(annotation = ComponentScan.class,attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};

顯然,通過它就能夠定義掃描哪些包。但是這里需要特別注意的是,它提供的exclude和excludeName兩個方法是對于其內(nèi)部的自動配置類才會生效的。為了能夠排除其他類,還可以再加入@ComponentScan以達到我們的目的。

條件裝配

  • 例如在數(shù)據(jù)庫連接池的配置中漏掉一些配置會造成數(shù)據(jù)源不能連接上。 在這樣的情況下, IoC容器如果還進行數(shù)據(jù)源的裝配, 則系統(tǒng)將會拋出異常,導致應用無法繼續(xù)。這時倒是希望IoC容器不去裝配數(shù)據(jù)源。
  • 為了處理這樣的場景, Spring 提供了@Conditional注解幫助我們,而它需要配合另外一個接口Condition(org.springframework.context.annotation.Condition )來完成對應的功能。

裝配的Bean:

@Bean(name = "dataSource", destroyMethod = "close" ) 
@Conditional(DatabaseConditional.class)
public DataSource getDataSource ( 
@Value("${database.driverName}") String driver, 
@Value("${database.url}") String url, 
@Value("${database.username}") String username, 
@Value("{database.password}") String password 
){ Properties props= new Properties(); props.setProperty("driver", driver); props setProperty("url", url); props.setProperty("username", username); props setProperty("password", password); DataSource dataSource = null; try { dataSource = BasicDataSourceFactory.createDataSource(props) ; ) catch (Exception e) { e.printStackTrace();}return dataSource;
}

自定義DatabaseConditional類:

public class DatabaseConditional implements Condition { 
/**
* 數(shù)據(jù)庫裝配條件
* 
* @param context 條件上下文
* @param metadata 注釋類型的元數(shù)據(jù)
* @return true 裝配 Bean,否則不裝配
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //取出環(huán)境配置Environment env = context.getEnvironment(); //判斷屬性文件是否存在對應的數(shù)據(jù)庫配置return env.containsProperty(”database.driverName” ) && env.containsProperty(”database.url”) && env.containsProperty(” database.username”) && env.containsProperty (”database.password");

matches 方法首先讀取其上下文環(huán)境, 然后判定是否已經(jīng)配置了對應的數(shù)據(jù)庫信息。這樣,當這些都己經(jīng)配置好后則返回true。這個時候Spring會裝配數(shù)據(jù)庫連接池的Bean,否則是不裝配的。

自定義Bean

  • 現(xiàn)實的Java 的應用往往需要引入許多來自第三方的包, 并且很有可能希望把第三方包的類對象也放入到Spring IoC 容器中,這時@Bean注解就可以發(fā)揮作用了。
  • 例如,要引入一個DBCP數(shù)據(jù)源,我們先在pom.xml上加入項目所需要DBCP包和數(shù)據(jù)庫MySQL驅(qū)動程序的依賴。
<dependency> <groupid>org.apache.commons</groupid> <artifactid>commons-dbcp2</artifactid> 
</dependency> 
<dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-ava</artifactid>
</dependency>

這樣 DBCP 和數(shù)據(jù)庫驅(qū)動就被加入到了項目中,接著將使用它提供的機制來生成數(shù)據(jù)源:

@Bean(name = "dataSource") 
@Conditional(DatabaseConditional.class)
public DataSource getDataSource (){ Properties props= new Properties(); props.setProperty("driver", driver); props setProperty("url", url); props.setProperty("username", username); props setProperty("password", password); DataSource dataSource = null; try { dataSource = BasicDataSourceFactory.createDataSource(props) ; ) catch (Exception e) { e.printStackTrace();}return dataSource;
}

這里通過@Bean 定義了其配置項 name 為“dataSource“,那么 Spring 就會把它返回的對象用名稱“dataSource” 保存在 loC 容器中。當然, 你也可以不填寫這個名稱,那么它就會用你的方法名稱作為Bean 名稱保存到 IoC 容器中。通過這樣,就可以將第三方包的類裝配到SpringIoC容器中了。


總結(jié)

以上就是SpringBoot的Bean裝配的詳細講解。

http://m.aloenet.com.cn/news/39890.html

相關文章:

  • 網(wǎng)站開發(fā)人員資質(zhì)濟南網(wǎng)絡推廣公司
  • 國外服務器公司有哪些網(wǎng)站功能優(yōu)化
  • wap仿制網(wǎng)站教程自己搭建一個網(wǎng)站
  • 建設京東類的網(wǎng)站需要什么流程域名搜索引擎
  • 監(jiān)控公司建設網(wǎng)站推廣經(jīng)營范圍最全bt磁力搜索引擎索引
  • 小程序 網(wǎng)站建設 app 開發(fā)網(wǎng)絡營銷知名企業(yè)
  • photoshop做圖網(wǎng)站如何利用互聯(lián)網(wǎng)宣傳與推廣
  • 可以做網(wǎng)站的公司軟件推廣接單平臺
  • 社區(qū)推廣普通話手機關鍵詞seo排名優(yōu)化
  • 畢業(yè)設計代做網(wǎng)站java湖南網(wǎng)站建設工作室
  • 設計師圖片素材網(wǎng)站適合企業(yè)員工培訓的課程
  • 網(wǎng)站建設的ci設計指的是什么視頻運營管理平臺
  • 宜興專業(yè)做網(wǎng)站公司搜索競價
  • 網(wǎng)站推廣被封域名如何做跳轉(zhuǎn)網(wǎng)站數(shù)據(jù)統(tǒng)計工具
  • 領地網(wǎng)做網(wǎng)站咋加文章廣告軟文小故事800字
  • 做律師網(wǎng)站的公司大二網(wǎng)絡營銷實訓報告
  • 網(wǎng)站建設課程 谷建軟文推廣服務
  • 南京疫情最新google seo是什么
  • 潮州專業(yè)網(wǎng)站建設制作百度競價排名黑幕
  • 網(wǎng)站鏈接查詢seo快速排名軟件首頁
  • 天津企業(yè)網(wǎng)站設計報價搜索引擎技術
  • 做招聘網(wǎng)站賺錢么百度知道推廣軟件
  • 上饒做網(wǎng)站網(wǎng)站備案流程
  • 網(wǎng)站備案號位置免費關鍵詞優(yōu)化工具
  • 網(wǎng)站開發(fā)實驗報告可行性分析簡單網(wǎng)站建設優(yōu)化推廣
  • asp 做購物網(wǎng)站成都全網(wǎng)營銷推廣
  • 模板商城建站網(wǎng)絡營銷的概念
  • 個人網(wǎng)站開發(fā)永久免費google搜索引擎
  • 延邊州建設局網(wǎng)站上海平臺推廣的公司
  • 用什么軟件做網(wǎng)站布局seo優(yōu)化主要做什么