@DeclareParents very interesting, take it alone, this can add a new common interface to the class that implements the same interface,
This allows you to convert to other types and have new methods without intruding into the original code.
This feature is called introductions in the Spring AOP documentation:
Introductions (known as inter-type declarations in AspectJ) enable the aspect to declare that advised objects implement a G Iven interface, and to provide a implementation of that interface on behalf of those objects.
An introduction is made using the @DeclareParents annotation. This annotation was used to declare that matching types has a new parent (hence the name). For example, given an interface usagetracked, and an implementation of that interface defaultusagetracked, the following a SPECT declares that all implementors of service interfaces also implement the Usagetracked interface.
The interface to be implemented are determined by the type of the annotated field. The value attribute of the @DeclareParents annotation is an AspectJ type pattern:-Any bean of a Matchi NG type would implement the Usagetracked interface. Note the before advice of the above example, service beans can be directly used as implementations of the USAG Etracked interface.
Continue to use COMPACTDISC and its implementation blankdisc
Compactdisc
Package Main.java.soundsystem; Public Interface Compactdisc { void play (); void Playtrack (Integer tracknumber);}
Blankdisc
PackageMain.java.soundsystem;Importjava.util.List; Public classBlankdiscImplementscompactdisc{PrivateString title; PrivateString artist; PrivateList<string>tracks; PublicBlankdisc Settitle (String title) { This. title =title; return This; } PublicBlankdisc setartist (String artist) { This. Artist =artist; return This; } PublicString GetTitle () {returntitle; } PublicString getartist () {returnartist; } Public voidSettracks (list<string>tracks) { This. Tracks =tracks; } Public voidPlay () {System.out.println ("Playing" + title + "by" +artist); if(tracks!=NULL) { for(String track:tracks) {System.out.println ("-track:" +Track ); } }} @Override Public voidPlaytrack (Integer tracknumber) {System.out.println ("Playing" +tracks.get (trackNumber-1)); }}
Define a new printer interface and its implementation cdprinter
Package Main.java.soundsystem; Public Interface Printer { void printcover ();}
PackageMain.java.soundsystem; Public classCdprinterImplementsPrinter {@Override Public voidPrintcover () {System.out.println ("Print CD cover ..." +Time ); } PublicString GetTime () {returnTime ; } Publiccdprinter settime (String time) { time=Time ; return This; } PrivateString time;
So how do you add new methods without modifying the COMPACTDISC and its implementation? Using @declareparent, use Java code configuration.
@DeclareParents has two parameter Value,defaultimpl,
Value indicates which classes are added to the new parent class interface, and the last "+" means adding an interface to all classes that implement the Compactdisc interface.
Defaultimpl represents the default implementation of the new interface, where the new interface is the printer interface that is added to the tag.
So all classes that implement the Compactdisc interface introduce the printer interface and have the methods in printer.
package Main.java.soundsystem; import Org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.DeclareParents; import Org.springframework.stereotype.Component; @Component @aspect public class Cdprinteraspect { @DeclareParents (value = "main.java.soundsystem.compactdisc+", Defaultimpl =cdprinter.class ) public static Printer Printer;}
Add the XML configuration and note that the printer corresponding Bean is not declared in the configuration.
<?XML version= "1.0" encoding= "UTF-8"?><Beansxmlns= "Http://www.springframework.org/schema/beans"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"Xmlns:context= "Http://www.springframework.org/schema/context"XMLNS:AOP= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"xsi:schemalocation= "Http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd Http://www.springframework.org/schema/context Http://www.springframework.org/schema/context/spring-co Ntext.xsd "> <Context:component-scanBase-package= "Main.java.soundsystem"/> <Aop:aspectj-autoproxy/> <BeanID= "Blankdisc"class= "Main.java.soundsystem.BlankDisc"> < Propertyname= "title"value= "Sgt. Pepper ' s Lonely heart Club Band"/> < Propertyname= "Artist"value= "The Beatles"/> < Propertyname= "Tracks"> <List> <value>Sgt Pepper ' s Lonely Hearts Club Band</value> <value>With a Little help from My Friends</value> <value>Lucy in the Sky with Diamonds</value> <value>Getting Better</value> <value>Fixing a Hole</value> </List> </ Property> </Bean></Beans>
Specifically used, the context uses BLANKDISC to generate an instance of Compactdisc, then explicitly converted to printer object, and using the method in which Cdprinter is implemented,
PackageMain.java.soundsystem;ImportOrg.springframework.context.ApplicationContext;ImportOrg.springframework.context.support.ClassPathXmlApplicationContext; Public classMain { Public Static voidMain (string[] args) {ApplicationContext context=NewClasspathxmlapplicationcontext ("Trackcounterconfig.xml"); Compactdisc CD= (Compactdisc) context.getbean ("Blankdisc"); Cd.play (); System.out.println ("\ncast to Printer\n"); ((Printer) CD). Printcover (); }}
Results:
Playing Sgt Pepper's Lonely Heart Club Band by the Beatles-track:sgt Pepper ' s Lonely Hearts Club band-Track:with A Little help from My Friends-track:lucyin the Sky with Diamonds-track:getting Better-track: Fixing a holecast to Printerprint CD cover ... NULL
Spring Combat-Fourth chapter -4.3 introductions& @DeclareParents