The successful and attractive point in the Spring framework is the management of container transactions, which provides a lightweight container transaction processing, targeting common Java classes. If Spring transaction management is used, you can incorporate some related methods into the transaction management according to your own business, which avoids Program The process of handling transactions is cumbersome. these are also attractive in ejb2.x specifications, which are well available in spring. although it is not provided in spring for cross-container transaction management, for general web programs, it is not necessary to use EJB only for those functions. however, recently, JBoss embedded EJB containers can also be smaller, which is also one of the open-source options. no matter how the technology develops, we will first study the implementation methods of AOP.
In fact, the transaction processing in spring is implemented through the AOP idea. Spring AOP is very different from aspect J and JBoss. First, one thing to remember when using the Spring AOP framework is that Spring AOP is intended for implementation at the method level, while the other two also provide support for fields. speaking of the inside story of Spring AOP, it is not difficult. For classes with interfaces, the proxy provided by the Java internal class is used. For classes without interfaces, the cglib library is used to dynamically create a subclass for implementation.
There are four types of processing intercept in Spring AOP: around, before, after, introduction. As the name suggests,
1) around is a method for a specific entry point (for example, there is an orderbook method now, And the und's cut-in type is called internally for this method through Java metadata, at runtime, use method. invoke is called and has a return value. It will be terminated in the event of an accident. remember that,Return Value.);
2) Before is called before the method call (called before the orderbook method, but there is no return value, and in general, it will continue to run the next method. Remember thatNo return value);
3) after and before are just the opposite. There is nothing special about them.
4) introduction is a more special, but more powerful cutting type. for example, you now have book objects, computer objects, and dozens of such business objects. Now you want to add the last modification time of a record to each of these objects. however, you do not want to modify each class because it is too troublesome and, more importantly, destroys the Object Integrity, maybe you don't need the time data in the future... what should we do? Spring AOP provides an introduction for you to specifically implement this idea. introduction can dynamically add some methods for you, so that you can forcibly convert these objects at runtime and insert time data. The deeper story is the vtable idea in the C ++ virtual function ). however, this kind of dynamic is at the price of performance. We should consider it carefully before using it. Here we talk about technology, so we think it is necessary.
Now let's take the fourth method to illustrate the strength of Spring AOP:
1) Suppose you have created a bookservice interface and its implementation method (Your Own Business Object ):
// $ ID: bookservice. Java created: 2005-11-6 by kerluse Benn
Package com. Osiris. springaop;
Public interface bookservice {
Public String ordercomputermagazine (string username, string bookname );
Public String orderbook (string username, string bookname );
}
// $ ID: bookserviceimpl. Java created: 2005-11-6 by kerluse Benn
Package com. Osiris. springaop;
Public class bookserviceimpl implements bookservice {
Public String orderbook (string name, string bookname ){
// Todo add your codes here
String result = NULL;
Result = "order" + bookname + "successful ";
Return result;
}
Public String ordercomputermagazine (string username, string bookname ){
// Todo add your codes here
String result = NULL;
Result = "order" + bookname + "successful ";
Return result;
}
}
2) In fact, You still have many such objects. Now we want to add the last modification time of our functions to each object. The functions are as follows:
// $ ID: iauditable. Java created: 2005-11-7 by kerluse Benn
Package com. Osiris. springaop. advices. Intruduction;
Import java. util. date;
Public interface iauditable {
Void setlastmodifieddate (date );
Date getlastmodifieddate ();
}
3) because we use introduction as the cut-in type, Spring AOP provides us with an introductioninterceptor to describe this type of interface, so we also need to implement this interface for our cut-in implementation:
// $ ID: auditablemixin. Java created: 2005-11-7 by kerluse Benn
Package com. Osiris. springaop. advices. Intruduction;
Import java. util. date;
Import org. aopalliance. Intercept. methodinvocation;
Import org. springframework. AOP. introductioninterceptor;
Public class auditablemixin implements iauditable, introductioninterceptor {
Private date lastmodifieddate;
Public object invoke (methodinvocation m) throws throwable {
// Todo add your codes here
If (implementsinterface (M. getmethod (). getdeclaringclass ())){
Return M. getmethod (). Invoke (this, M. getarguments ());
// Invoke introduced mthod, here is iauditable
} Else {
Return M. Proceed (); // delegate other method
}
}
Public date getlastmodifieddate (){
// Todo add your codes here
Return lastmodifieddate;
}
Public void setlastmodifieddate (date ){
// Todo add your codes here
Lastmodifieddate = date;
}
Public Boolean implementsinterface (class CLs ){
// Todo add your codes here
Return Cls. isassignablefrom (iauditable. Class );
}
}
4) OK. Now the Business Object bookservice class is available and iauditable is available for the processing you want to add. The question of using the Spring AOP framework is left. Configure the bean. xml file:
<? XML version = "1.0" encoding = "UTF-8"?>
<! Doctype beans public "-// spring // DTD bean // en ""Http://www.springframework.org/dtd/spring-beans.dtd">
<Beans>
<! -- Beans -->
<Bean id = "bookservicetarget" class = "com. Osiris. springaop. bookserviceimpl" Singleton = "false"/>
<! -- Introduction advice -->
<Bean id = "auditablemixin" class = "com. Osiris. springaop. advices. Intruduction. auditablemixin" Singleton = "false"/>
<! -- Introduction advisor -->
<Bean id = "auditableadvisor" class = "org. springframework. AOP. Support. defaultintroductionadvisor"
Singleton = "false">
<Constructor-Arg>
<Ref bean = "auditablemixin"/>
</Constructor-Arg>
</Bean>
<Bean id = "bookservice" class = "org. springframework. AOP. Framework. proxyfactorybean">
<Property name = "target">
<Ref bean = "bookservicetarget"/>
</Property>
<Property name = "Singleton">
<Value> false </value>
</Property>
<! -- Force to use cglib -->
<Property name = "proxytargetclass">
<Value> true </value>
</Property>
<! -- Introduction methods -->
<Property name = "proxyinterfaces">
<Value> com. Osiris. springaop. advices. Intruduction. iauditable </value>
</Property>
<Property name = "interceptornames">
<List>
<Value> auditableadvisor </value>
</List>
</Property>
</Bean>
</Beans>
The above is the configuration file. Now we assume that the business object is used as follows. Here is a simple test class:
// $ ID: mainapp. Java created: 2005-11-6 by kerluse Benn
Package com. Osiris. springaop;
Import java. util. date;
Import org. springframework. Beans. Factory. beanfactory;
Import org. springframework. Beans. Factory. xml. xmlbeanfactory;
Import org. springframework. Core. Io. filesystemresource;
Import com. Osiris. springaop. advices. Intruduction. iauditable;
Public class mainapp {
/**
* @ Param ARGs
* @ Author kerluse Benn
*/
Public static void main (string [] ARGs) throws exception {
// Todo add your codes here
Beanfactory factory = new xmlbeanfactory (New filesystemresource ("bean. xml "));
Bookservice = (bookservice) Factory. getbean ("bookservice ");
Iauditable auditable = (iauditable) bookservice;
System. Out. Print (bookservice. orderbook ("kerluse Benn", "professional C #"));
Auditable. setlastmodifieddate (new date ());
System. Out. println ("order time:" + auditable. getlastmodifieddate ());
Thread. Sleep (10000 );
System. Out. Print (bookservice. orderbook ("kerluse Benn", "expert J2EE one-on-one "));
Auditable. setlastmodifieddate (new date ());
System. Out. println ("order time:" + auditable. getlastmodifieddate ());
}
}
Output result:
Professional C # successful order time: Mon Nov 07 11:35:20 CST 2005
Order expert J2EE one-on-one successfully purchased at Mon Nov 07 11:35:30 CST 2005
See the above italics:
Iauditable auditable = (iauditable) bookservice;
Because the bookservice object has actually implemented the iauditable interface and is implemented through the introduction of Spring AOP, it can be converted during runtime (when you are familiar with the c ++ vtable model, you can think about it in the brain, we can add our own interface methods at will.
well, I will introduce Spring AOP. For more information, see relevant books, the purpose of this Article is to introduce the strength of the AOP application. specific applications also include user operation verification.