In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
The editor will share with you how to configure the data source in @ PropertySource in the spring annotation. I hope you will get something after reading this article. Let's discuss it together.
@ PropertySource data source configuration
Generally speaking, when configuring a data source, you will use xml injection, and key-value is managed in properties. Spring4.X has relatively perfect annotations to replace the configuration of xml.
Configure the data source using xml
Usually we use xml to configure the data source and SpEL to get the configuration in properties.
Configure dataSource and PreferencesPlaceholderConfigurer in applicationContext.xml, and replace Bean attributes with PropertyPlaceholderConfigurer
Classpath:/jdbc.properties
Jdbc.properties
Proxool.alias=mySqlproxool.driver=com.mysql.jdbc.Driverproxool.driverUrl=jdbc:mysql://localhost:3306/test?characterEncoding=utf8proxool.user=rootproxool.password=rootproxool.maximumActiveTime=1200proxool.maximumConnectionCount=50#... Configure the data source using javaBean
The DataSourceConfiguration class is the javaBean configuration of the data source. @ Configuratio annotations the current class.
When spring starts, it scans the class annotated by @ Configuratio and injects the method bean configured in the current class.
Of course, don't forget to enable annotation scanning:
@ value comment read configuration
You can directly use SpEL in @ value to obtain properties configuration, and getter and setter are not required for member variables. However, there is a prerequisite: you need to configure xml:
Classpath:/jdbc.properties
@ Bean note: when spring scans the current class, the return value Bean of each method annotated with @ Bean is injected. The name attribute defaults to the lowercase case of the return value class name. Set name here.
Package com.XXX.test.dateSource;import org.logicalcobwebs.proxool.ProxoolDataSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuratiopublic class DataSourceConfiguration {@ Value ("${proxool.alias}") private String alias; @ Value ("${proxool.driver}") private String driver; @ Value ("${proxool.driverUrl}") private String driverUrl @ Value ("${proxool.user}") private String user; @ Value ("${proxool.password}") private String password; / /. @ Bean (name= "dataSource") public ProxoolDataSource dataSource () {ProxoolDataSource proxoolDataSource = new ProxoolDataSource (); proxoolDataSource.setDriver (driver); proxoolDataSource.setDriverUrl (driverUrl); proxoolDataSource.setUser (user); proxoolDataSource.setPassword (password); / /. Return proxoolDataSource;}}
At this time, dataSource has been injected, and can be annotated when in use, as follows:
@ Autowired private ProxoolDataSource dataSource;@PropertySource comment read configuration
@ PropertySource annotations the current class, and the parameter is the corresponding configuration file path. In this way, you don't have to configure PropertiesFactoryBean in xml to introduce jdbc.properties. It is much easier to use. DataSourceConfiguration no longer needs member variables. Instead, you need to inject an Environment environment configuration and use env.getProperty (key) to obtain data:
Package com.XXX.test.dateSource;import org.logicalcobwebs.proxool.ProxoolDataSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.core.env.Environment;@Configuratio@PropertySource ("classpath:/jdbc.properties") public class DataSourceConfiguration {@ Autowired private Environment env Bean (name= "dataSource") public ProxoolDataSource dataSource () {ProxoolDataSource proxoolDataSource = new ProxoolDataSource (); proxoolDataSource.setDriver (env.getProperty ("proxool.alias")); proxoolDataSource.setDriverUrl (env.getProperty ("proxool.driver")); proxoolDataSource.setUser (env.getProperty ("proxool.user")); proxoolDataSource.setPassword (env.getProperty ("proxool.password")); / /. Return proxoolDataSource;}}
This is mainly about the use of annotations, so it does not specifically reflect the configuration of all the parameters of the data source. For those with obsessive-compulsive disorder, if all bean in the project use annotations, it is almost impossible to expect only dataSource to be configured with the xml class, and the sense of obsessive-compulsive class configuration will disappear in a class-like way!
Configuration and use of annotated spring multiple data sources
Some time ago, I studied the configuration and use of spring multi-data sources, in order to prepare for data analysis and report statistics by pulling data from multiple data sources at a later time. Since all the projects I have done before are from single data sources, I have not encountered such a scenario, so I have never learned how to configure multiple data sources.
Later, it was found that it is relatively simple to configure and use multiple data sources based on spring, because the spring framework has reserved such an interface to facilitate the switching of data sources.
First take a look at spring to get the source code of the data source.
You can see that before AbstractRoutingDataSource gets the data source, it calls the determineCurrentLookupKey method to find the current lookupKey, and this lookupKey is the data source identity.
So by overriding this method of finding the identity of the data source, you can switch the spring to the specified data source.
Step 1: create a class for DynamicDataSource
Inherit AbstractRoutingDataSource and rewrite the determineCurrentLookupKey method as follows:
Public class DynamicDataSource extends AbstractRoutingDataSource {@ Override protected Object determineCurrentLookupKey () {/ / get the data source identity return DynamicDataSourceHolder.getDataSource () from a custom location;}} step 2: create a DynamicDataSourceHolder
Used to hold the data source identity used in the current thread, the code is as follows:
Public class DynamicDataSourceHolder {/ * Note: the data source identity is saved in thread variables to avoid interference with each other when multithreading operates on the data source * / private static final ThreadLocal THREAD_DATA_SOURCE = new ThreadLocal (); public static String getDataSource () {return THREAD_DATA_SOURCE.get ();} public static void setDataSource (String dataSource) {THREAD_DATA_SOURCE.set (dataSource) } public static void clearDataSource () {THREAD_DATA_SOURCE.remove ();}} step 3: configure multiple data sources
And the bean of DynamicDataSource created in the first step, the simplified configuration is as follows:
Now that you can use multiple data sources, just DynamicDataSourceHolder.setDataSource ("dataSource2") can switch to data source 2 and operate on the database db2 before operating the database.
The sample code is as follows:
@ Servicepublic class DataServiceImpl implements DataService {@ Autowired private DataMapper dataMapper; @ Override public List getList1 () {/ / is not specified, then data source 1 return dataMapper.getList1 ();} @ Override public List getList2 () {/ / specify to switch to data source 2 DynamicDataSourceHolder.setDataSource ("dataSource2"); return dataMapper.getList2 () } @ Override public List getList3 () {/ / specify to switch to data source 3 DynamicDataSourceHolder.setDataSource ("dataSource3"); return dataMapper.getList3 ();}}
-- gorgeous dividing lines--
But here's the problem: it's cumbersome to call DynamicDataSourceHolder.setDataSource ("xxx") every time you switch data sources, and it's easy to miss out with a large amount of code, and it's troublesome to maintain it later. Can you specify the data source you need to access directly through annotations, such as using @ DataSource ("xxx") in the dao layer to specify access to the data source xxx? Yes, of course! The premise is to add a little extra configuration ^ _ ^.
First, we have to define an annotation called DataSource, with the following code:
Target ({TYPE, METHOD}) @ Retention (RUNTIME) public @ interface DataSource {String value ();}
Then, define the AOP section to intercept all methods with the annotation @ DataSource, and take the value of the annotation as the data source identity and put it in the thread variable of DynamicDataSourceHolder:
Public class DataSourceAspect {/ * intercepts the target method, gets the data source identity specified by @ DataSource, and sets it to thread storage to switch the data source * * @ param point * @ throws Exception * / public void intercept (JoinPoint point) throws Exception {Class target = point.getTarget (). GetClass (); MethodSignature signature = (MethodSignature) point.getSignature () / / the annotations of the target type are used by default. If not, the annotations of the implementation interface for (Class clazz: target.getInterfaces ()) {resolveDataSource (clazz, signature.getMethod ());} resolveDataSource (target, signature.getMethod ()) are used. } / * extract data source identities in target object method annotations and type annotations * * @ param clazz * @ param method * / private void resolveDataSource (Class clazz, Method method) {try {Class [] types = method.getParameterTypes () / / default type annotations if (clazz.isAnnotationPresent (DataSource.class)) {DataSource source = clazz.getAnnotation (DataSource.class); DynamicDataSourceHolder.setDataSource (source.value ());} / / method annotations can override type annotations Method m = clazz.getMethod (method.getName (), types) If (m! = null & & m.isAnnotationPresent (DataSource.class)) {DataSource source = m.getAnnotation (DataSource.class); DynamicDataSourceHolder.setDataSource (source.value ());}} catch (Exception e) {System.out.println (clazz + ":" + e.getMessage ());}
Finally, you can configure the interception rules in the spring configuration file, such as intercepting all the methods in the service layer or dao layer:
OK, so that you can specify the data source directly with the annotation @ DataSource on the class or method, without having to set it manually every time.
The sample code is as follows:
@ Service// all methods under the default DataServiceImpl access data source 1@DataSource ("dataSource1") public class DataServiceImpl implements DataService {@ Autowired private DataMapper dataMapper; @ Override public List getList1 () {/ / is not specified, then data source 1 return dataMapper.getList1 () is used by default } @ Override / / override the specified on the class, use data source 2 @ DataSource ("dataSource2") public List getList2 () {return dataMapper.getList2 ();} @ Override / / override the specified on the class, use data source 3 @ DataSource ("dataSource3") public List getList3 () {return dataMapper.getList3 ();}}
Tip: note @ DataSource can be added either to a method or to an interface or an interface's implementation class, with priority: method > implementation class > interface. That is, if the @ DataSource annotation is added to the interface, the interface implementation class, and the method to specify the data source, then the specified method takes precedence.
After reading this article, I believe you have a certain understanding of "how to configure data sources in the spring annotation @ PropertySource". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.