Professional Documents
Culture Documents
released today
p
c
W
{
p
s
v
m
(S
[ a
){
W
w
1=n
W
()
W
w
2=n
W
()
w
1.d
()
w
2.d
()
w
1.d
()
}
p
v
d
(){
S
s
=S
.asp
().g
()
S
.o .p
( Do
wo
in"+s
doWo
1()
doWo
2()
}
p
voiddoWo
1(){
S
s
=S
.asp
S
.o .p
+s
)
}
p
voiddoWo
S
s
().g
()
S
.o .p
+s
)
}
}
("Doingwo
=S
inh
2(){
1fo "
.asp
("Doingwo
inh
2fo "
Worker has a convenience main method that creates two workers and
asks them to do work. Note that the doWorkHelper1() and
doWorkHelper2() methods are called within the cflow of the doWork
method. In each method we print out the current session (from the
SessionManager aspect). The SessionManager aspect is a percflow
aspect that creates a new aspect for each control flow through
doWork....
@B
("S
p
asp
p
p
S
S
")
s
fac
(s
()){
/**
*S
tous isconfigu
*/
pub
voids
(S
facto ){
this.facto =facto
}
/**
*Ma
th cu
s
avai
toan
who
n
it
*/
pub
S
g
(){r
s
}
/**
*An
S
(ands
)b
wh
*w e
doWor
*/
pointcutsession():e
(*doWor (..))
/**
*Createasessionusingthefactor
passedto
*uswhenwewereconfigured
*/
thatwas
session=factor .beginSession()
}
/**
*C
thesessionattheendofthesession()
contro
*f
.
*/
after():session(){session.c
()}
}
Note that the SessionManager aspect is annotated with @Bean, and has
a setSessionFactory(..) method that is to be called by an IoC
container to pass it the session factory to use.
Here's the Spring beans.xml file for the project. Note that this is
100% standard Spring, no funny stuff.
Just compile this with the Spring AspectJ library on your aspectpath
and run main:
Doingwor
Doingwor
Doingwor
Doingwor
Doingwor
Doingwor
Doingwor
Doingwor
Doingwor
insession#1001
inhe
1forsession#1001
inhe
2forsession#1001
insession#1002
inhe
1forsession#1002
inhe
2forsession#1002
insession#100
inhe
1forsession#100
inhe
2forsession#100
/**
*Configureandva
an ob
whoset
is
annotatedwith@Bean.
*Va
occursforan t
imp
the
Va
*interface.Tobesubc
foreachIoCmechanism
youwantto
*support(eg.Spring,HiveMind,Pico,JD ,...).
*/
pub
abstractaspectBeanConfigurator{
/**
*Weon
va
@Beans...
*/
dec
warning:staticinitia
(Va
+)&&
!staticinitia
(@Bean*)&&
!staticinitia
(Va
)
:"Imp
ofVa
must
havethe@Beanannotation"
/**
*Thecreationofanewbean(anob
withthe@
Beanannotation)
*/
pointcutbeanCreation(BeanbeanAnnotation,Ob
beanInstance):
initia
((@Bean*).new(..))&&
@this(beanAnnotation)&&
this(beanInstance)
/**
*A
beansshou
beconfiguredafterconstruction.
*/
after(BeanbeanAnnotation,Ob
beanInstance)
returning:
beanCreation(beanAnnotation,beanInstance)
{
configureBean(beanInstance,getBean
(beanAnnotation,beanInstance))
}
/**
*Ifabeanimp
theVa
*va
()onitonceithasbeenconfigured
(thisadvicerunsafterthe
*configurationadvice).
*/
after(BeanbeanAnnotation,Va
beanInstance)returning:
beanCreation(beanAnnotation,Ob
)&&this
(beanInstance){
beanInstance.va
()
}
/**
*Thebeannameiseithertheva
giveninthe
annotation(@Bean("MyBean")),
*orthenameofthetypeifnova
isgiven
(@Bean).
*/
privateStringgetBean
(BeanbeanAnnotation,
Ob
beanInstance){
Stringbean
=beanAnnotation.va
()
if(bean
.e
(""))bean
=
beanInstance.getC
().get
()
returnbean
}
/**
*Tobeoverridenbysub:aspects.Configurethe
beaninstanceusingthegiven
*beanname.
*/
protectedabstractvoidconfigureBean(Ob
bean,Stringbean
)
}
This abstract aspect has been designed to allow you to plug-in any
IoC container you choose. We chose Spring ;). So here's the concrete
Spring sub-aspect:
/**
*Configurationofany@BeanusingSpring
*/
pub
aspectSpringBeanConfiguratorextends
BeanConfigurator
imp
App
{
privateConfigurab
bean
/**
*DItheSpringapp
contextinwhichthis
aspectshou
configurebeans.
pub
voidsetApp
(App
ctx){
if(!(ctxinstanceof
Configurab
)){
thrownewAspectConfigurationException(
"App
["+ctx+"
doesnotimp
Configurab
.")
}
bean
=((Configurab
)
ctx).getBean
()
}
/**
*Imp
ofconfigureBeanfromthesuper:
aspect
*/
protectedvoidconfigureBean(Ob
bean,String
bean
){
if(bean
!=nu &&
bean
.containsBeanDefinition(bean
)){
bean
.app
(bean,bean
)
}
}
}
/**
*Imp
la
initiali
ofSpringbasedon
firstuseofan
*@Beantype.
*/
publicabstractaspectAbstractSpringInitiali
{
/**
*weonlywanttocreatetheapplicationcontext
once
*/
staticbooleaninitiali
=false
/**
*thefirsttimeweloadatypewiththe@Bean
annotation
*/
pointcutfirstTime
():
(!initiali
)
/**
*CreatetheSpringapplicationcontext,delegate
creationstrategyto
*concretesub:aspects.
*/
after()returning:firstTime
(){
ApplicationContextcontext=
createApplicationContext()
SpringBeanConfigurator.aspectOf
().setApplicationContext(context)
}
/**
*Sub:aspectsoverridethismethodtoprovidea
concretestrategyfor
*applicationcontextcreation.
*/
protectedabstractApplicationContext
createApplicationContext()
}
/**
*Adefaultimplementationofthe
AbstractSpringInitiali
aspect.Thiswillconfigure
*theSpringapplicationcontextusingthesetof
beans.xmlfilesavailableintheclasspath
*(whatyouwantformanyapplications).Configuration
filescanbeoverridenbyspecifying
*the
org.aspect .a
.configuration.spring.config
property(usefulfortestingetc.).
*/
publicaspectDefaultSpringInitiali
extends
AbstractSpringInitiali
{
publicstaticfinalStringCO
_LOCATIO
=
"org.aspect .a
.configuration.spring.configLocations"
privatestaticfinalStringDE
_LOCATIO _PATTE
="classpath*:/**/beans.xml"
protectedApplicationContextcreateApplicationContext
Stringconfig
=null
try{
config
=System.getProperty
(CO
_LOCATIO )
if(config
==null)
config
=DE
_LOCATIO _PATTE
}catch(SecurityExceptionsecEx){
config
=DE
_LOCATIO _
PATTE
}
returnnewClassPath
(
StringUtils.commaDelimitedListToStringArray
(config
))
}
}
The result of all this, is that with a few very simple building
blocks you can configure aspects (and any other type) simply by
writing a standard beans.xml file and using the @Bean annotation no Spring APIs required in your code at all. There's more coming out
of the joint Spring / AspectJ development effort, but I hope this
whets your appetite for now.
Posted by adrian at March 22, 2005 03:47 PM [permalink]
Comments
Very cool. Now, when you say any type, does that refer to plain java
beans?
Posted by: Peter Morelli at March 22, 2005 04:01 PM
Yes, although bear in mind this solution works best in situations
where you are programmatically creating instances (or in the case of
AspectJ, the AspectJ runtime is creating instances of aspects for
you) that you subsequently want to be configured. For the "normal"
pre-instantiated and wired-together singletons model that Spring
supports you wouldn't need to use @Bean since Spring handles
instantiation and configuration in one go.
Posted by: Adrian at March 22, 2005 06:34 PM
Post a comment
You are not signed in. You need to be registered to comment on this
site. Sign in