1 o+ M& p1 Q( k: `0 E@MyScope注解对应的Scope实现如下 2 K+ `0 f5 e: Q; P 1 ~5 v v0 l4 U# S' m' Ipackage com.javacode2018.lesson002.demo18.test3;; p4 U$ F% x/ T: S5 H6 ~, ?
8 u `8 `8 g6 h" w& F
import org.springframework.beans.factory.ObjectFactory; 5 p2 y( o0 j5 j7 ^import org.springframework.beans.factory.config.Scope; 0 \7 N% c& \! t* d* O" F6 eimport org.springframework.lang.Nullable; 7 p8 g1 P* d# b# D% G! M n& @ _( V9 y. L E9 i/** V J& J: m0 d9 m5 [0 _8 d * @see MyScope 作用域的实现 # w- h8 X* P. C9 }" g */ 5 R5 }0 C- D b% Cpublic class BeanMyScope implements Scope {0 r2 f2 b" c2 X' n; |& L9 d
# U" n$ q0 d b- V' x- @
public static final String SCOPE_MY = "my"; //@1 3 w p6 ]( K- O" I) U6 A5 D: o& u2 E; F, G( o3 z+ [
@Override, e8 M+ ~& ?5 Q. o3 I
public Object get(String name, ObjectFactory<?> objectFactory) { 2 E5 C8 \, Q* I2 J4 ]# g# H& F( m System.out.println("BeanMyScope >>>>>>>>> get:" + name); //@2, B( }% y( k6 _4 m6 @* i$ A
return objectFactory.getObject(); //@3 * p# h* }3 v8 }5 W+ `# H9 A0 p1 D } * X* b J0 ~9 ?3 [9 @/ q" F+ ?0 z5 h4 q2 R5 s& S
@Nullable+ U6 v+ I5 G. H( B0 ~
@Override ) R1 `7 `/ O% Q public Object remove(String name) {. A( ~, k% q1 P$ B2 V" {3 Q
return null; + E, y, s' @' T3 s; P) p8 X }" k9 |3 d" e3 [ A
, V _7 R- m$ E3 h @Override- P2 g$ E0 Z, A% L* H# e$ t
public void registerDestructionCallback(String name, Runnable callback) { 7 M9 T2 s4 ^3 ^4 d; } 8 X$ x b+ m; T# @0 X6 E/ z3 H } 2 Q# o1 p9 X4 E7 P- ?* X. p; W( i! a4 F0 s; {
@Nullable + I+ u& Q5 Q6 N7 }- S) K @Override. Q0 G! i6 N; b: J( B! y! G# P) e& ]
public Object resolveContextualObject(String key) {; F9 {; q3 p* o# D) k `
return null;& e1 a' \7 p, A
} {1 |7 K4 B0 w' l' {
1 P, w* [: v: Y+ B @Nullable 3 Z3 ^& q k* c$ B# T8 F3 z @Override, b( k Q3 [9 ?3 b7 v
public String getConversationId() {; l; u) h2 u- e+ c: o
return null;" T; x$ k. O8 y* Y8 I* _5 L
} + U) O6 F, B4 `7 `$ @( M& I: i}7 R+ K+ C& i& x. @ P. u
@1:定义了一个常量,作为作用域的值 . Y( ?7 c' R% N: @ 3 P; Q9 o: W- D@2:这个get方法是关键,自定义作用域会自动调用这个get方法来创建bean对象,这个地方输出了一行日志,为了一会方便看效果+ b' n3 z9 k1 T7 w
% x" r5 b, }2 ]/ k& |) a
@3:通过objectFactory.getObject()获取bean实例返回。 3 X& ]1 T- P: G* c" a4 m% x. p' ^4 Q$ c: Z
下面来创建个类,作用域为上面自定义的作用域 S" n4 ]$ P, `
B `( F& q& D* p3 M
package com.javacode2018.lesson002.demo18.test3;; |3 k) n- i! q& S
% t$ C; a! I& i9 j& g
import org.springframework.stereotype.Component; 6 @; {# ^2 D- ]5 }- c( a! ~8 F 2 D9 p0 y% r1 zimport java.util.UUID; ' F9 `3 X, F! k9 V0 A# q/ M5 U; r6 O# L1 P2 D7 A. O
@Component+ s1 x8 @8 C) g% j+ k" r/ b6 z. s$ _
@MyScope //@1 ; t& s- U/ W! a5 ~) gpublic class User {8 y0 b% f% d; H+ J8 A: `
% ]. }& L0 j6 }/ b* u: u1 u
private String username; - K$ U8 @2 Z) t0 N / F6 b x$ i; ^. L1 r: w) D public User() { b. d1 H8 u. f. \+ ?4 W. [- i3 n' r System.out.println("---------创建User对象" + this); //@2( w6 R0 Q3 F- _6 f3 H) {
this.username = UUID.randomUUID().toString(); //@3& l3 C- t. B+ X3 U$ L
} 1 k# O* u) `$ s( Z9 D) @# F" ]1 t
public String getUsername() { 9 v* a& C/ K. M$ B* T) R. A return username; 6 \" @, O9 R. V, b1 Z }* e& q8 r; M3 t; H) o9 E
# C+ R) N: C# B( K ~- J% x$ } public void setUsername(String username) { , ?, |% I1 e5 O7 [) @ this.username = username;" P* W; H* ~* p; Y
}/ u+ F% @ Q4 x1 m$ R. V
7 Y# Y* O3 K) p+ R8 q/ m
} . ^1 N# L0 @7 h- J# u@1:使用了自定义的作用域@MyScope , e) ]2 T; p, W4 c: c) Z" M$ {* w9 r0 b. z$ C% A
@2:构造函数中输出一行日志 : h F Q+ ^4 J. r: h7 r+ e. ^) O* V! w! Z/ w) r. s
@3:给username赋值,通过uuid随机生成了一个 9 E% z0 \( N8 T* L$ v/ b- i0 d5 `) X. d4 j8 r3 d+ \
来个spring配置类,加载上面@Compontent标注的组件7 U6 S! [" N( ^9 T6 o5 f4 d1 g1 k
8 i5 ?, j. W1 {- o+ }3 p6 Spackage com.javacode2018.lesson002.demo18.test3; ( |8 }- e$ R( ?3 u7 T8 R0 b( \% }# O2 j3 k
import org.springframework.context.annotation.ComponentScan; : _. ]- ?, D2 |* R, eimport org.springframework.context.annotation.Configuration;$ Q' c- B0 @" f1 v; x0 ~
) f6 P9 f. ^0 I: } W8 P6 o% w7 E
@ComponentScan, `5 Y( v( T$ B( K7 Z
@Configuration. B9 {) g8 _: ~; ^
public class MainConfig3 {8 l d! i0 l3 R8 Y' `) B
}- _, A A4 j9 G3 W; O
下面重点来了,测试用例 2 y4 u, i- k5 f2 {$ ?" n2 J d 2 ?" x0 \3 G& b% E; H: {$ _3 B@Test 9 b# z7 t) U$ @8 Y7 `- }public void test3() throws InterruptedException { 3 X/ \) `! p+ k+ p5 ~3 E6 \ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();( o* m( a, Q! ^- M# r7 s4 v' `/ U# i
//将自定义作用域注册到spring容器中& C8 O b+ h; o5 G4 C
context.getBeanFactory().registerScope(BeanMyScope.SCOPE_MY, new BeanMyScope());//@1& J6 _* ?, n. |/ W9 y4 u; }
context.register(MainConfig3.class);! ^7 Z% N; l) o r& q& N: N! M
context.refresh(); * w4 L* y# ^. w4 g/ B, k4 b; c, {+ [( C' |# |* I6 j
System.out.println("从容器中获取User对象");% ~4 Y: i) n, l9 n# j* C
User user = context.getBean(User.class); //@2 [8 H4 b* c. a
System.out.println("user对象的class为:" + user.getClass()); //@3/ j% I/ m9 Y" j# n5 p) G; q+ m6 T
% Q; |9 f+ K3 K+ R System.out.println("多次调用user的getUsername感受一下效果\n");3 j5 i+ W' P+ l Q$ S
for (int i = 1; i <= 3; i++) {$ B" @0 Y8 h, s. K5 k; m
System.out.println(String.format("********\n第%d次开始调用getUsername", i));8 l6 g- T$ F1 t8 o
System.out.println(user.getUsername()); . W' U f" ~8 N3 z9 f# t, \ System.out.println(String.format("第%d次调用getUsername结束\n********\n", i));# k" d* k& ]6 E8 `7 m
}! `3 n1 B9 o# ]& L
}' u3 B3 ] f) X3 W5 |2 s' `4 y. K$ u
@1:将自定义作用域注册到spring容器中- x* x% f9 i- K, v) p" E. R
$ J9 i' M' d( r$ u! m; s
@2:从容器中获取User对应的bean1 r6 p3 Z t, z& [5 F