在springboot中我們經(jīng)??梢砸胍恍﹕tarter包來集成一些工具的使用,比如spring-boot-starter-data-redis
。
使用起來很方便,那么是如何實(shí)現(xiàn)的呢?
代碼分析
我們先看注解@springbootapplication
,它里面包含一個(gè)@enableautoconfiguration
繼續(xù)看@enableautoconfiguration注解
@import({autoconfigurationimportselector.class})
在這個(gè)類(autoconfigurationimportselector)里面實(shí)現(xiàn)了自動(dòng)配置的加載
主要代碼片段:
string[] selectimports(annotationmetadata annotationmetadata)方法中
1
|
autoconfigurationimportselector.autoconfigurationentry autoconfigurationentry = this .getautoconfigurationentry(autoconfigurationmetadata, annotationmetadata); |
getautoconfigurationentry方法中:
1
2
3
4
5
6
7
|
list<string> configurations = this .getcandidateconfigurations(annotationmetadata, attributes); protected list<string> getcandidateconfigurations(annotationmetadata metadata, annotationattributes attributes) { list<string> configurations = springfactoriesloader.loadfactorynames( this .getspringfactoriesloaderfactoryclass(), this .getbeanclassloader()); assert .notempty(configurations, "no auto configuration classes found in meta-inf/spring.factories. if you are using a custom packaging, make sure that file is correct." ); return configurations; } |
最后會(huì)通過springfactoriesloader.loadspringfactories去加載meta-inf/spring.factories
1
2
|
enumeration<url> urls = classloader != null ? classloader.getresources( "meta-inf/spring.factories" ) : classloader.getsystemresources( "meta-inf/spring.factories" ); linkedmultivaluemap result = new linkedmultivaluemap(); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
while (urls.hasmoreelements()) { url url = (url)urls.nextelement(); urlresource resource = new urlresource(url); properties properties = propertiesloaderutils.loadproperties(resource); iterator var6 = properties.entryset().iterator(); while (var6.hasnext()) { entry<?, ?> entry = (entry)var6.next(); string factoryclassname = ((string)entry.getkey()).trim(); string[] var9 = stringutils.commadelimitedlisttostringarray((string)entry.getvalue()); int var10 = var9.length; for ( int var11 = 0 ; var11 < var10; ++var11) { string factoryname = var9[var11]; result.add(factoryclassname, factoryname.trim()); } } } |
zookeeperautoconfiguration
我們來實(shí)現(xiàn)一個(gè)zk的autoconfiguration
首先定義一個(gè)zookeeperautoconfiguration類
然后在meta-inf/spring.factories中加入
1
|
org.springframework.boot.autoconfigure.enableautoconfiguration=com.fayayo.fim.zookeeper.zookeeperautoconfiguration |
接下來我們看看具體的實(shí)現(xiàn):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
@configurationproperties (prefix = "fim.register" ) @configuration public class urlregistry { private string address; private int timeout; private int sessiontimeout; public string getaddress() { if (address == null ) { address = urlparam.address; } return address; } public void setaddress(string address) { this .address = address; } public int gettimeout() { if (timeout == 0 ) { timeout = urlparam.connecttimeout; } return timeout; } public void settimeout( int timeout) { this .timeout = timeout; } public int getsessiontimeout() { if (sessiontimeout == 0 ) { sessiontimeout = urlparam.registrysessiontimeout; } return sessiontimeout; } public void setsessiontimeout( int sessiontimeout) { this .sessiontimeout = sessiontimeout; } } @configuration @enableconfigurationproperties (urlregistry. class ) @slf4j public class zookeeperautoconfiguration { @autowired private urlregistry url; @bean (value = "registry" ) public registry createregistry() { try { string address = url.getaddress(); int timeout = url.gettimeout(); int sessiontimeout = url.getsessiontimeout(); log.info( "init zookeeperregistry,address[{}],sessiontimeout[{}],timeout[{}]" , address, timeout, sessiontimeout); zkclient zkclient = new zkclient(address, sessiontimeout, timeout); return new zookeeperregistry(zkclient); } catch (zkexception e) { log.error( "[zookeeperregistry] fail to connect zookeeper, cause: " + e.getmessage()); throw e; } } } |
zookeeperregistry部分實(shí)現(xiàn):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public zookeeperregistry(zkclient zkclient) { this .zkclient = zkclient; log.info( "zk register success!" ); string parentpath = urlparam.zookeeper_registry_namespace; try { if (!zkclient.exists(parentpath)) { log.info( "init zookeeper registry namespace" ); zkclient.createpersistent(parentpath, true ); } //監(jiān)聽 zkclient.subscribechildchanges(parentpath, new izkchildlistener() { //對(duì)父節(jié)點(diǎn)添加監(jiān)聽子節(jié)點(diǎn)變化。 @override public void handlechildchange(string parentpath, list<string> currentchilds) { log.info(string.format( "[zookeeperregistry] service list change: path=%s, currentchilds=%s" , parentpath, currentchilds.tostring())); if (watchnotify!= null ){ watchnotify.notify(nodechildstourls(currentchilds)); } } }); shutdownhook.registershutdownhook( this ); } catch (exception e) { e.printstacktrace(); log.error( "failed to subscribe zookeeper" ); } } |
具體使用
那么我們?cè)趺词褂米约簩懙膠ookeeperautoconfiguration呢
首先要在需要使用的項(xiàng)目中引入依賴
1
2
3
4
5
|
<dependency> <groupid>com.fayayo</groupid> <artifactid>fim-registry-zookeeper</artifactid> <version> 0.0 . 1 -snapshot</version> </dependency> |
然后配置參數(shù)
1
2
3
4
|
fim: register: address: 192.168 . 88.129 : 2181 timeout: 2000 |
如果不配置會(huì)有默認(rèn)的參數(shù)
具體使用的時(shí)候只需要在bean中注入就可以了,比如
1
2
3
4
5
6
7
8
9
10
|
@autowired private registry registry; public list<url> getall(){ list<url>list=cache.get(key); if (collectionutils.isempty(list)){ list=registry.discover(); cache.put(key,list); } return list; } |
完整代碼
https://github.com/lizu18xz/fim.git
總結(jié)
以上所述是小編給大家介紹的springboot 中 autoconfiguration的使用方法,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!原文鏈接:https://www.imooc.com/article/285008