Spring Boot Tomcat JDBCプールのプロパティバインディングコードを見てみましょう。特定のコードは次のとおりです。
春:データソース:タイプ:org.apache.tomcat.jdbc.pool.datasource driver-class-name:org.postgresql.driver url:jdbc:postgresql://192.168.99.100:5432/postgres = 6000&sockettimeout = 6000 uspradsut = 6000 username jmx-enabled:true initial-size:1 max-active:5 ##プールセーターが有効になっている場合、追加のアイドル接続が閉じます。
上記の構成を使用して、イニシャルサイズ、Max-Active、Max-Idle、Min-Idle、およびその他の構成が無効であることが最終的にわかりました。生成されたTomcat JDBC DataSourceは、まだ使用されているデフォルトの構成です。
正しい構成
春:データソース:タイプ:org.apache.tomcat.jdbc.pool.datasource driver-class-name:org.postgresql.driver url:jdbc:postgresql://192.168.99.100:5432/postgres = 6000&sockettimeout = 6000 uspradsut = 6000 username jmx-exabled:true tomcat:##単一のデータベース接続プールで、Tomcatプロパティ構成を有効にするために書き込む必要があります:1 max-active:5 ##プールスイーパーが有効になると、追加のアイドル接続が閉じます。
特定のTomcatデータベース接続プールの構成プロパティは、spring.datasource.tomcatプロパティの下に配置されているため、有効になります。
ソースコード分析
Spring-boot-autoconfigure-1.5.9.Release-sources.jar!/org/springframework/boot/autoconfigure/jdbc/datasourceautoconfiguration.java@configuration @conditional(pooleddatasourcecondition.class.class. Xadatasource.class})@import({datasourceconfiguration.tomcat.class、datasourceconfiguration.hikari.class、datasourceconfiguration.dbcp.class、datasourceconfiguration.dbcp2.class @suppresswarnings( "deprecation")保護された静的クラスPooledDataSourceConfiguration {}DataSourceConfiguration.tomcat
Spring-boot-autoconfigure-1.5.9.Release-sources.jar!/org/springframework/boot/autoconfigure/jdbc/datasourceconfiguration.java/*** tomcatプールデータソース構成。 */ @ConditionAlonClass(org.apache.tomcat.jdbc.pool.datasource.class)@conditionalonproperty(name = "spring.datasource.type"、havevalue = "org.apache.tomcat.jdbc.pool.datasous" dataSourceConfiguration {@bean @configurationProperties(prefix = "spring.datasource.tomcat")public org.apache.tomcat.jdbc.datasource datasource(datasourceproperties Properties){org.apache.tomcat.jdbc.pool.pool.poolce createdAtaSource(Properties、org.apache.tomcat.jdbc.pool.datasource.class); DatabasedRiver DataBasedRiver = databasedRiver .FromJdbcurl(properties.DetermineUrl()); string validationQuery = databasedRiver.getValidationQuery(); if(validationQuery!= null){dataSource.settestonborrow(true); dataSource.setValidationQuery(ValidationQuery); } dataSourceを返します。 }}ここのデータソースプロパティには、spring.datasourceの直接属性の構成のみがあることがわかります。 Tomcatには特定の特性がありません。
createdatasource
protected <t> t recutedAtaSource(dataSourcePropertiesプロパティ、クラス<?extends dataSource> type){return(t)properties.initializatasourcebuilder()。type(type).build(); }org.apache.tomcat.jdbc.pool.datasource Poolpropertiesは、直接createdAtaSourceもデフォルトの構成でもあります。
ConfigurationProperties
特定の魔法は、コード@ConfigurationProperties(prefix = "spring.datasource.tomcat")にあります。スプリングコンテナがプロキシビーンを構築して戻る前に、spring.datasource.tomcatで指定された属性をorg.apache.tomcat.jdbc.pool.datasourceに設定します。
spring-boot-1.5.9.Release-sources.jar!/org/springframework/boot/context/properties/configurationpropertiesbindingpostprocessor.javaprivate void postprocessbeforeInitialization(object bean、sring beanname、configurationproperties andation){object = bean; propertiesConfigurationFactory <Object> Factory = new PropertiesConfigurationFactory <Object>(ターゲット); Factory.setPropertySources(this.PropertySources); Factory.setValidator(sequinevalidator(bean)); //明示的な変換サービスが提供されていない場合は、(少なくとも)//コンバーチブルのコンマ分離アレイを自動的にfactory.setconversionservice(this.conversionservice == null?getDefaultConversionservice():this.conversionservice); if(annotation!= null){factory.setignoreInvalidfields(annotation.ignoreInvalidfields()); Factory.setignoreUnknownFields(annotation.ignoreunknownfields()); Factory.setexceptionifinvalid(annotation.exceptionifinvalid()); Factory.setignorEnestedProperties(annotation.ignorenestedProperties()); if(stringutils.haslength(annotation.prefix())){factory.settargetname(annotation.prefix()); }} try {factory.bindPropertIestOtarget(); } catch(Exception ex){string targetclass = classutils.getShortName(target.getClass());新しいbeancreationexception(beanname、 "プロパティを" + targetclass + "(" + getAnnotationDetails + ")"にバインドできませんでした。 }}ここの注釈は@ConfigurationProperties(prefix = "spring.datasource.tomcat")であることに注意してください。そのプレフィックスはspring.datasource.tomcat PropertiesConfigurationFactory targetnameです。
propertiesConfigurationFactory.bindPropertArtargetSpring-Boot-1.5.9.Release-sources.jar!/org/springframework/boot/bind/propertiesconfigurationfactory.javapublic void void bindpropertiThtarget()Throws bindexcepti null "); try {if(logger.istraceEnabled()){logger.trace( "プロパティソース:" + this.propertySources); } this.hasbeenbound = true; dobindpropertiestotarget(); } catch(bindexception ex){if(this.exceptionifinvalid){throw ex; } propertiesConfigurationFactory.Logger .Error( "プロパティ検証Beanのロードに失敗しました。" + "あなたのプロパティは無効になる可能性があります。"、ex); }}DobindPropertiestOtargetメソッドに委任します
PropertiesConfigurationFactory.DobindPropertIestOtargetPrivate void dobindpropertiestotarget()throws bindexception {rackeddatabinder databinder =(this.targetname!= null?new rackeddatabinder(this.target、this.targetname):new rackeddatabninder(this.target); if(this.validator!= null && this.validator.supports(databinder.getTarget()。getClass()){dataBinder.setValidator(this.Validator); } if(this.conversionservice!= null){databinder.setConversionservice(this.Conversionservice); } dataBinder.setAutogrowCollectionLimit(integer.max_value); databinder.setignorenestedProperties(this.ignorenestedproperties); databinder.setignoreInvalidfields(this.ignoreInvalidfields); databinder.setignoreunknownfields(this.ignoreunknownfields); CustomizeBinder(dataBinder); iterable <string> rackedTargetNames = getRelaxedTargetNames(); <string> names = getNames(rackedTargetNames)を設定します。 PropertyValues PropertyValues = getPropertySourcesPropertyValues(名前、rackedTargetNames); databinder.bind(propertyValues); if(this.validator!= null){databinder.validate(); } checkforbindingerrors(databinder); }ここでは、rackeddatabinder.bindメソッドを使用してください
getRelaxedTargetNamesPrivate iterable <string> getRelaxedTargetNames(){return(this.target!= null && stringutils.haslength(this.targetname)?new raxednames(this.targetname):null); }複数の変数のバリエーションを識別できる新しいリラックス名があります
リラックス名
spring-boot-1.5.9.Release-sources.jar!/org/springframework/boot/bind/relaxednames.javaprivate void initialize(string name、set <string> values){if(values.contains(name)){return; } for(variation variation:variation.values()){for(manipulation manipulation:manipulation.values()){string result = name; result = manipulation.apply(result); result = variation.apply(result); values.add(result);初期化(結果、値); }}} /***名前のバリエーション。 */ enum variation {none {@override public string apply(string value){return value; }}、lowercase {@override public string apply(string value){return value.isempty()?値:value.tolowercase(); }}、appercase {@override public string apply(string value){return value.isempty()?値:value.touppercase(); }};パブリックアブストラクト文字列apply(string value); }つまり、org.springframework.boot.bind.relaxednames@6ef81f31の構成方法の作成方法spring.datasource.tomcat、spring_datasource_tomcat、springdatasourcetomcat]]がサポートされています。
getPropertySourcesPropertyValuesprivateプロパティバリューgetPropertySourcesPropertyValues(set <string> names、iterable <string> rackedTargetNames){propertyNamepatternsmatcher include = getPropertynamepatternsmatcher(names、larbedtargetnames);新しいpropertySourcesPropertyValues(this.propertySources、names、include、this.resolveplaceholders)を返します。 }この方法は、spring.datasource.tomactの下でプロパティ構成をPropertyValuesオブジェクトに引っ張ります
rackeddatabinder.bind
spring-boot-1.5.9.Release-sources.jar!/org/springframework/boot/bind/relaxeddatabinder.java's bindメソッドは、親クラスのメソッドを呼び出します。 * <p>この呼び出しは、必要なフィールド(コード「必須」)などの基本的なバインディング *エラーを表す、またはvalueとbeanプロパティ(コード "typemismatch")の間の型のミスマッチ *を表すフィールドエラーを作成できます。 * <p>指定されたプロパティバリューは、使い捨てのインスタンスである必要があることに注意してください。 *効率のために、可変プロパティバリューインターフェイスを実装する場合、許可されたフィールドのみを含むように変更されます。それ以外の場合、この目的のために内部可変 *コピーが作成されます。プロパティバリューのコピーを渡します*元のインスタンスがいずれにせよ修正されていないようにしたい場合。 * @Param PVSバインドするプロパティ値 * @see #Dobind(org.springframework.beans.mutablepropertyvalues) */ public void bind(propertyvalues pvs){mutablepropertyvalues mpvs =(pvs instance of mutablepropertyvalues)? (MutablePropertyValues)PVS:新しいMutablePropertyValues(PVS); Dobind(MPVS); } /** *バインディングプロセスの実際の実装。 * @Param MPVSバインドするプロパティ値、 * MutablePropertyValues Instance * @see #checkallowedfields * @see #checkrequiredfields * @seee #applypropertyvalues */保護されたボイドdobind(mutablepropertyvalues mpvs){mpvs(mpvs); CheckRequiredFields(MPVS); ApplyPropertyValues(MPVS); } /***指定されたプロパティ値をターゲットオブジェクトに適用します。 * <p>デフォルトの実装は、提供されたすべてのプロパティ *値をBeanプロパティ値として適用します。デフォルトでは、不明なフィールドは無視されます。 * @Param MPVSバウンドするプロパティ値(変更できます) {//ターゲットオブジェクトにリクエストパラメーターをバインドします。 getPropertyAccessor()。setPropertyValues(MPVS、isignoreUnknownFields()、isignoreInvalidfields()); } catch(PropertyBatchUpDateException ex){// Bind Error Processorを使用してFielderRorsを作成します。 for(propertyaccessexception pae:ex.getPropertyAccesSexceptions()){getBindingErrorProcessor()。processPropertyAccessexception(pae、getinternalbindingResult()); }}} /***このバインダーのbindingResultの基礎となるプロパティアクセサーを返します。 */ protected configureablepropertyaccesser getPropertyaccessor(){return getInternalBindingResult()。getPropertyAccessess(); }最後に、getPropertyAccesser()によって設定されます。このPropertyAccessorはorg.springframework.boot.bind.relaxeddatabinder $ raxedbeanwrapper:wrapping object [org.apache.tomcat.jdbc.pool.datasource@6a84bc2a]、frapped org.apache.tomcat.jdbc.pool.datasouceです。
proptropertyaccessess.setPropertyValuessPring-Beans-4.3.13.Release-sources.jar!/org/springframework/beans/abstractpropertyacsesser.java@override public void setpropertyvalues(Propertyvalues pvs)リスト<PropertyAccesSexception> PropertyAccesSexceptions = null; List <PropropetValue> PropertyValues =(PVS Instance of MutablePropertyValues?(((MutablePropertyValues)PVS).GetPropertyValuelist():arrays.Aslist(pvs.getPropertyValues()); for(PropertyValue PV:PropertyValues){try {//このメソッドは、一致するフィールドがないなどの重大な障害がある場合、ここでキャッチされないBeanSexceptionをスローする場合があります。 //それほど深刻ではない例外のみを扱うことを試みることができます。 SetPropertyValue(PV); } catch(notWritablePropertyException ex){if(!nignoreunknown){throw ex; } //それ以外の場合は、それを無視して続行するだけです...} catch(nullvalueinnestedpathexceptecection ex){if(!nagroreinvalid){shrow ex; } //それ以外の場合は、それを無視して続行します...} catch(propertyaccessexception ex){if(propertyaccessexceptions == null){propertyaccessexceptions = new linkedlist <propropatiaChessexception>(); } propertyAccesSexceptions.add(ex); }} //個々の例外に遭遇した場合は、複合例外をスローします。 if(propertyaccessexceptions!= null){propertyaccessexception [] paearray = propertyaccessexceptions.toarray(new PropertyAccesSexception [propertaCcessexceptions.size()]);新しいPropertyBatchUpDateException(PaeArray)を投げる; }} @Override public void setPropertyValue(PropertyValue PV)Throws BeanSexception {PropertyTokenHolder Tokens =(PropertyTokenHolder)pv.ResolvedTokens; if(tokens == null){string propertyname = pv.getName(); abstractnestablePropertyAccesser Nestedpa; try {nestedpa = getPropertyaccesserforPropertyPath(propertyName); } catch(notreadablePropertyException ex){new NotWritablePropertyException(getRootClass()、this.nestedPath + propertyName、「パスのネストされたプロパティ」 " + propertyName +" '' not not not in to ex)、ex); } tokens = getPropertynameTokens(getFinalPath(nestedpa、propertyname)); if(nestedpa == this){pv.getoriginalpropertyvalue()。resolvedTokens = tokens; } nestedpa.setPropertyValue(Tokens、PV); } else {setPropertyValue(tokens、pv); }}ここでNestedPa.setPropertyValue(Tokens、PV); spring.datasource.tomcatプロパティ値の実際の設定はorg.springframework.boot.bind.relaxeddatabinder $ rackedbeanwrapper:wrapping object.jdbc.pool.datasource@6a84bc2a]
processlocalpropertyspring-beans-4.3.13.Release-sources.jar!/org/springframework/beans/abstractnestablepropertyaccess.javaprate void processlocalproperty(Propetitokenholder tokens、Propertyvalue pvhenthler eppvhenthen epvhenther epv) getLocalPropertyHandler(tokens.actualname); if(ph == null ||!ph.iswritable()){if(pv.isoptional()){if(logger.isdebugenabled()){ogger.debug( "プロパティのオプション値を無視する" + tokens.actualname + "' - プロパティはbean class [" } 戻る; } else {throw createNotWritablePropertyException(tokens.CanonicalName); }} object oldvalue = null; try {object originalvalue = pv.getValue();オブジェクトValueToApply = originalValue; if(!boolean.false.equals(pv.conversionn diseersary)){if(pv.isconverted()){valuetoApply = pv.getConvertedValue(); } else {if(isextractoldValueForeditor()&& ph.isreadable()){try {oldvalue = ph.getValue(); } catch(Exception ex){if(ex instanceof intanceof intance exception){ex =(((primiledactionexception)ex).getException(); } if(logger.isdebugenabled()){logger.debug( "プロパティの以前の値を読み取れなかった '" + this.nestedpath + tokens.canonicalname + "'"、ex); }} valueOpapply = convertforProperty(tokens.canonicalName、oldvalue、originalValue、ph.totypedescriptor()); } pv.getoriginalpropertyvalue()。conversionn diseversary =(valueToApply!= originalValue); } ph.setValue(this.wrappedObject、valueToApply); } catch(typemismatchException ex){show ex; } catch(InvocationTargetException ex){propertyChangeEvent PropertyChangeEvent = new PropertyChangeEvent(this.rootobject、this.nestedpath + tokens.canonicalname、oldvalue、pv.getvalue()); if(ex.getTargetException()instanceof classcastException){throw new TypeMismatchException(PropertyChangeEvent、Ph.GetPropertyType()、Ex.GetTargetException()); } else {throwable cause = ex.getTargetException(); if(原因のないexceptionのインスタンス){//グルーヴィー生成方法で発生する可能性があります。 }新しいmethod invocationException(propertyChangeEvent、couse)をスローします。 }} catch(Exception ex){propertyChangeEvent PCE = new PropertyChangeEvent(this.rootobject、this.nestedpath + tokens.canonicalname、oldvalue、pv.getvalue());新しいMethodInvocationException(PCE、EX)を投げる; }}クラスorg.springframework.beans.beanwrapperimpl $ beanpropertyhandlerを使用して設定します
beanwrapperimpl$beanpropertyhandler.setvaluespring-beans-4.3.13.Release-sources.jar!/org/springframework/beans/beanwrapperimpl.java@override public void setValue(最終オブジェクトオブジェクト、オブジェクトvalueToply) generictypeawarepropertydescriptor? if(!modifier.ispublic(wretemethod.getDeclaringClass()。getModifiers())&&!writemethod.isaccessible())){if(system.getSecurityManager()!= null){accessController.Dopriviledeged(新しいArifileDecation <Objectedaction() writemethod.setAccessible(true)}}; } else {writemethod.setAccessible(true); }}最終オブジェクト値= ValuEToApply; if(system.getSecurityManager()!= null){try {AccessController.Doprivileded(new PrivileGedExceptionaction <Object>(){@Override public object run()throws {writemethod.invoke(object、value); return null;}}、acc); } catch(priviledecationexception ex){ex.getException(); }} else {writemethod.invoke(getWrappingInstance()、value); }}}}ここでは、反射を使用してsetxxxメソッド(setmaxactiveなど)を見つけてから、
マルチデータソース構成
上記の構成は、単一のデータソースでは問題ではありません。複数のデータソースの場合、構成は次のとおりです
@configurationPublic Class MasterDataSourceConfig {@Bean( "MasterDataSource")@configurationProperties(prefix = "spring.datasource.master")public datasource(){){return datasourcebuilder.create()。ビルド()。 }}ConfigurationPropertiesをTomcat JDBCプールに挿入するには、追加の設定を追加する必要があることに注意してください
春:データソース:マスター:タイプ:org.apache.tomcat.jdbc.pool.datasource driver-class-name:org.postgresql.driver url:jdbc://192.168.99.100:5432/postgres = 6000&sockettimeut = 6000 usertimeut = 6000&sockettimeut = 6000&sockettimeut = 6000 jmx-exabled:true#tomcat:##複数のデータソースの場合、ここでTomcatを削除し、データソースのプレフィックスの下に置く必要があります初期サイズ:1 max-active:5 ##はプールスイーパーが有効になると閉じます。
元のTomcat構成はデータソースプレフィックスの下に配置する必要があり、spring.datasource.tomcatまたはspring.datasource.master.tomcatで有効になることはできません。