锘??xml version="1.0" encoding="utf-8" standalone="yes"?> ------------------------------------------- ------------------------------------------ For all those out there using Spring together with Struts, i created
a small howTo regarding automatic generation of relevant files,
especially the boring action-servlet-xml file which must be in synch
with your struts-config.xml, at least for all Struts actions which
should be injected by Spring. Lets start with the Action class: ClientManager clientManagerService; /** With this tags, the ant build target outlined below will create a
struts-config.xml and the necessary action-servlet.xml needed by
Spring. Lets see how the target looks: <fileset dir="c:/xdoclet-1.2.2" includes="*.jar"/> <taskdef name="springdoclet" <target name="myTest"> <springdoclet destDir="c:\" verbose="true"> Be sure to modify the classpath definition and the destDir values of
springdoclet and webdoclet to suit your needs. Right now the Spring
task only searches for Actions in order to create action-servlet.xml,
if you also want to create your normal service beans like
ClientManagerService, you should create another springdoclet task and
output things to applicationContext.xml if you like. But this is mostly users choice, as you know, Spring supports from
one to many bean definition files and its up to you how you want to
have your spring xml world. This will be created when you run the mentioned target: (action-servlet.xml) <beans <bean <property name="clientManagerService"> <ref bean="clientManagerService"/> </bean> <!-- <!DOCTYPE struts-config PUBLIC "-//Apache Software
Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <!-- ========== Data Sources Definitions =================================== --> <!-- ========== Form Bean Definitions =================================== --> <!-- <!-- ========== Global Exceptions Definitions =================================== --> <!-- ========== Global Forward Definitions =================================== --> <!-- ========== Action Mapping Definitions =================================== --> <!-- If you have non XDoclet actions, define them in a file
called struts-actions.xml and place it in your merge directory. --> <!-- Define your Struts controller in a file called struts-controller.xml and place it in your merge directory. --> <!-- Define your Struts message-resources in a file called
struts-message-resources.xml and place it in your merge directory.
--> <!-- Define your Struts plugins in a file called struts-plugins.xml and place it in your merge directory. -->
XDoclet鐨刡uild.xml鍐欐硶
錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳錛濓紳
---------------------------------------------
/**
* Action to delete a Client
* Date: 09.02.2005
* Time: 15:29:15
*
* @author Logemann - Logentis e.K. (ml@logentis.de)
* @version $Id$
* @struts.action path="clientDelete" validate="false"
* type="org.springframework.web.struts.DelegatingActionProxy"
* name="emptyform"
* @struts.action-forward name="back"
* path="/clientManager.html" redirect="true"
* @spring.bean name="clientDelete"
*/
public class ClientDeleteAction extends Action {
* Spring injection
*
* @param clientManagerService clientManagerService
* @spring.property ref="clientManagerService"
*/
public void setClientManagerService(ClientManager clientManagerService) {
this.clientManagerService = clientManagerService;
}
[..]
<path id="classpath">
<fileset dir="c:/j2sdkee1.3.1/lib" includes="*.jar"/>
<fileset dir="c:/struts/lib" includes="struts.jar"/>
</path>
classname="xdoclet.modules.spring.SpringDocletTask"
classpathref="classpath"/>
<taskdef name="webdoclet"
classname="xdoclet.modules.web.WebDocletTask"
classpathref="classpath"/>
<webdoclet destDir="c:\" force="true" verbose="true">
<fileset dir="${src.dir}">
<include name="**/*Form.java" />
<include name="**/*Action.java" />
<include name="**/*Servlet.java" />
</fileset>
<strutsconfigxml version="1.1" validateXml="true"/>
</webdoclet>
<fileset dir="${src.dir}">
<include name="**/*Action.java" />
</fileset>
<springxml destinationFile="action-servlet.xml"/>
</springdoclet>
</target>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
default-autowire="no"
default-lazy-init="false"
default-dependency-check="none"
>
name="clientDelete"
class="de.logentis.versysng.action.clientmanager.ClientDeleteAction"
>
</property>
To include additional bean definitions for Spring in the generated
application context file, add a file to your XDoclet merge directory
called spring-beans.xml that contains the <bean></bean> markup.
-->
</beans>
(struts-config.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Define your Struts data sources in a file called struts-data-sources.xml and place
it in your merge directory.
-->
<form-beans>
If you have non XDoclet forms, define them in a file called struts-forms.xml and
place it in your merge directory.
-->
</form-beans>
<!--
Define your exceptions in a file called global-exceptions.xml and place
it in your merge directory.
-->
<!--
Define your forwards in a file called global-forwards.xml and place
it in your merge directory.
-->
<action-mappings>
<action
path="clientDelete"
type="org.springframework.web.struts.DelegatingActionProxy"
name="emptyform"
scope="request"
unknown="false"
validate="false"
>
<forward
name="back"
path="/clientManager.html"
redirect="true"
/>
</action>
</action-mappings>
CHAPTER 2 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
CHAPTER 3 The Sample Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
PART 2 鈻?鈻?鈻?Spring Basics
CHAPTER 4 Introducing Inversion of Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
CHAPTER 5 Beyond the Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
PART 3 鈻?鈻?鈻?Aspect Oriented Programming
with Spring
CHAPTER 6 Introducing Spring AOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
CHAPTER 7 More on Spring AOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
PART 4 鈻?鈻?鈻?Data Access with Spring
CHAPTER 8 Spring JDBC Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
CHAPTER 9 Using Hibernate in Spring Applications . . . . . . . . . . . . . . . . . . . . . . . 279
CHAPTER 10 iBATIS Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
vi 鈻燙ONTENTS AT A GLANCE
PART 5 鈻?鈻?鈻?Spring in the Middle Tier
CHAPTER 11 Designing and Implementing Spring-Based Applications . . . . . . 353
CHAPTER 12 Transaction Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
CHAPTER 13 Spring and J2EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
CHAPTER 14 Job Scheduling with Spring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
CHAPTER 15 Mail Support in Spring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
CHAPTER 16 Using Spring Remoting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
PART 6 鈻?鈻?鈻?Web Applications with Spring
CHAPTER 17 Web Applications with Spring MVC . . . . . . . . . . . . . . . . . . . . . . . . . . 599
CHAPTER 18 Beyond JSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
CHAPTER 19 Spring and Struts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
PART 7 鈻?鈻?鈻?Appendixes
APPENDIX A Testing with Spring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
APPENDIX B The Spring Rich Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711
APPENDIX C Spring IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
APPENDIX D The Future of Spring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743
<bean id="transactionManager" //瀵?/SPAN>JDBC Transaction鐨勫皝瑁?/SPAN>
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="transactionManager" //瀵?/SPAN>Hibernate浜嬪姟鐨勫皝瑁?/SPAN>
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="transactionManager"http://瀵?/SPAN>JDO浜嬪姟鐨勫皝瑁?/SPAN>
class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory">
<ref bean="persistenceManagerFactory"/>
</property>
</bean>
<bean id="transactionManager" //瀵?/SPAN>JTA 浜嬪姟鐨勫皝瑁?/SPAN>
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName">
<value>java:/TransactionManager</value>
</property>
</bean>
<bean id="courseService"http://鍒╃敤AOP錛屽皢TransactionManager鍜屾櫘閫氱殑Service緙栫粐璧鋒潵錛屽疄鐜頒簨鍔°?/SPAN>
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces">//緙栫粐鍚庡澶栫殑鎺ュ彛
<list>
<value>com.springinaction.training.service.CourseService</value>
</list>
</property>
<property name="target">//鐩爣
<ref bean="courseServiceTarget"/>
</property>
<property name="transactionManager">//妞嶅叆鐨勪簨鍔$鐞嗚?/SPAN>
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">//浜嬪姟鐨勫弬鏁幫紙闅旂搴︼紝鏂規硶鍚嶇瓑錛?/SPAN>
<ref bean="attributeSource"/>
</property>
</bean>
鏈変袱縐嶆墜孌碉細1銆佷嬌鐢?/SPAN>HibernateTemplate錛?/SPAN>2銆佺戶鎵?/SPAN>HibernateDaoSupport錛堝疄闄呬笂錛?/SPAN>HibernateDaoSupport鏈韓灝辨槸瀵?/SPAN>HibernateTemplate鐨勪竴涓皝瑁咃級
涓鍒囧敖鍦ㄤ唬鐮佷腑錛屾煡鐪?/SPAN>API鍞夛紒
娉ㄦ剰錛歨ibernate 2.X鍜宧ibernate3.X鐨勫尯鍒紝鎴戠敤鐨勬槸2.X 銆?nbsp;
package com.company.example.dao;
import java.util.List;
import com.company.example.model.Student;
public interface StudentDao {
public abstract Student getStudent(final Integer id);
public abstract void updateStudent(Student student);
public abstract List findStudentsByLastName(String lastName);
}
==================
package com.company.example.dao.hibernateImpl;
import java.util.List;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.HibernateTemplate;
import com.company.example.dao.StudentDao;
import com.company.example.model.Student;
public class StudentDaoHibernate implements StudentDao {
HibernateTemplate hibernateTemplate;
public static void main(String[] args) {
}
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public Student getStudent(final Integer id) {
return (Student) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
return session.load(Student.class, id);
}
});
}
public Student getStudent2(Integer id) {
return (Student) hibernateTemplate.load(Student.class, id);
}
public void updateStudent(Student student) {
hibernateTemplate.update(student);
}
public List findStudentsByLastName(String lastName) {
return hibernateTemplate.find("from Student student "
+ "where student.lastName = ?", lastName, Hibernate.STRING);
}
}
public class StudentDaoHibernate extends HibernateDaoSupport
implements StudentDao {
...........
}
======The Spring XML Configuration===========
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"<beans>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/trainingDatasource</value>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="mappingResources">
<list> <!--list of each hbm.xml-->
<value>Student.hbm.xml</value>
<value>Course.hbm.xml</value>
</list>
</property>
<property name="mappingDirectoryLocations">
<list>
<!--list the directory of the hbm.xml, including each xml file in the dir-->
<value>classpath:/com/springinaction/training/model</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="studentDao" class="com.company.example.dao.hibernateImpl.StudentDaoHibernate">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
<bean id="courseDao" class="com.company.example.dao.hibernateImpl.CourseDaoHibernate">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
</beans>
灝佽鎵鏈夌殑鏁版嵁搴撹闂疄鐜幫紝鍖呮嫭JDBC,JDO,Hibernate絳夈?/SPAN>
Spring鐨勫紓甯鎬竴鑸兘鏄?/SPAN>RuntimeException錛屾暟鎹闂殑鏍瑰紓甯告槸DataAccessException錛屾墍鏈夌殑Spring鐨勬暟鎹闂紓甯擱兘緇ф壙DataAccessException銆傛澶?/SPAN>DataAccessException鐨?/SPAN>nestedRuntimeException瀛愮被涓紝宸茬粡灝嗘墍鏈夌殑寮傚父鏍堥兘榪涜浜嗚褰曘?/SPAN>
Spring鐨?/SPAN>DAO寮傚父瀵規墍鏈夊簳灞傜殑DAO璁塊棶瀹炵幇灞傜殑寮傚父榪涜浜嗙粺涓鐨勫皝瑁咃紝騫剁粰鍑轟簡鏇翠負鏈夋剰涔夌殑寮傚父銆?/SPAN>
CleanupFailureDataAccessException錛氭竻闄ゅけ璐ュ紓甯?/SPAN>
DataAccessResourceFailureException錛氳祫婧愯闂紓甯?/SPAN>
DataIntegrityViolationException錛氬畬鏁存х害鏉熷紓甯?/SPAN>
DataRetrievalFailureException錛氭暟鎹幏鍙栧紓甯?/SPAN>
DeadlockLoserDataAccessException錛氭閿佽闂紓甯?/SPAN>
IncorrectUpdateSemanticsDataAccessException錛氭洿鏂板嚭閿欏紓甯?/SPAN>
InvalidDataAccessApiUsageException錛氭棤鏁堟暟鎹闂?/SPAN>API浣跨敤寮傚父
InvalidDataAccessResourceUsageException錛氭棤鏁堟暟鎹闂祫婧愪嬌鐢ㄥ紓甯?/SPAN>
OptimisticLockingFailureException錛氫箰瑙傞攣澶辮觸寮傚父
TypeMismatchDataAccessException錛氱被鍨嬪尮閰嶅け璐ュ紓甯?/SPAN>
UncategorizedDataAccessException錛氬叾浠栧師鍥犲紓甯?BR>
Spring浣跨敤Template鍜?/SPAN>Callback妯″紡瀹屾垚浜嗗搴曞眰瀹炵幇鐨勭粺涓灝佽錛屽叾涓?/SPAN>Template璐熻矗瀹屾垚閭d簺閫氱敤鐨勫姛鑳斤紙澶勭悊浜嬪姟銆佺鐞嗚祫婧愩佸鐞嗗紓甯革級錛?/SPAN>Callback鍒欏畬鎴愬彉鍖栫殑閭i儴鍒嗗唴瀹癸紙鍒涘緩statement銆佽瀹氬弬鏁?/SPAN>parameter銆佺敓鎴愭暟鎹泦result錛夈傚弬鑰冨浘4.2銆?/SPAN>4.3澶噸瑕佷簡銆?/SPAN>
姝e鍓嶉潰宸茬粡鎻愬埌鐨勶紝Introduction鍜屽墠闈㈢殑鍥涗釜advice鏄湁寰堝ぇ鐨勫尯鍒殑錛?/SPAN>introduction鐢ㄤ簬緇?/SPAN>target寮曞叆鏂扮殑鎺ュ彛錛堜緥濡傞攣錛岀姸鎬佺瓑鍔熻兘錛夛紝鐢熸垚涓涓?/SPAN>mix-in鐨勬帴鍙c傝屾櫘閫氱殑advice鍙槸鍦ㄥ師鏈夋帴鍙e熀紜涓婂鍔犻檮鍔犲唴瀹廣?/SPAN>
鍦?/SPAN>Spring涓紝瀹屾垚涓涓?/SPAN>introduction闇瑕佷笁涓唴瀹癸細1銆佸皢瑕佹坊鍔犵殑鏂版帴鍙g殑瀹氫箟錛?/SPAN>2銆佽鏂版帴鍙g殑瀹炵幇錛屽湪瀹炵幇鐨?/SPAN>class涓紝蹇呴』瀹炵幇Spring鐨?/SPAN>IntroductionInterceptor鎺ュ彛錛?/SPAN>Spring in action鍘熸枃鏈夎錛夛紝3銆?/SPAN>IntroductionAdvisor鎺ュ彛鐨勫疄鐜?/SPAN>銆?/SPAN>
public interface IntroductionInterceptor extends MethodInterceptor {
boolean implementsInterface(Class intf);
java.lang.Object invoke(MethodInvocation invocation) //姝ゆ柟娉曟潵婧愪簬MethodInterceptor
}
鍏朵腑implementsInterface鏂規硶榪斿洖涓涓?/SPAN>boolean鍊鹼紝姝ゆ柟娉曠敤浜庡垽鏂introduction瀹炵幇鏄惁瀹炵幇浜嗘煇涓帴鍙b曗?/SPAN>intf鍙傛暟銆傛墍鏈夊intf鎺ュ彛鐨勮皟鐢ㄩ兘浼氳漿鍙戠粰invoke鏂規硶錛岀敱invoke鏂規硶瀹屾垚鐩稿簲鐨勪換鍔°備笅闈㈢粰鍑轟緥瀛愶紙緇欐煇涓被娣誨姞鏄惁auditable鍔熻兘錛夛細
public interface Auditable {//1銆?/SPAN>auditable鎺ュ彛鐨勫畾涔?/SPAN>
void setLastModifiedDate(Date date);
Date getLastModifiedDate();
}
public class AuditableMixin
implements IntroductionInterceptor, Auditable {//2銆?/SPAN>auditable鎺ュ彛鐨勫疄鐜幫紝鍚屾椂瑕佸疄鐜?/SPAN>IntroductionInterceptor鎺ュ彛
public boolean implementsInterface(Class intf) {
return intf.isAssignableFrom(Auditable.class); // AuditableMixin瀹炵幇浜?/SPAN>Auditable綾葷殑鍔熻兘
}
public Object invoke(MethodInvocation m) throws Throwable {
if (implementsInterface(m.getMethod().getDeclaringClass())) {
//瀵?/SPAN>invoke鐨勫弬鏁?/SPAN>m榪涜鍒ゆ柇錛屽綋鍓嶇殑璋冪敤鏄惁鍦?/SPAN>implementsInterface鑼冨洿鍐咃紝鍗籌紝褰撳墠鐨勮皟鐢ㄦ槸鍚︽槸auditable鎺ュ彛涓殑鏂規硶錛?/SPAN>
return m.getMethod().invoke(this, m.getArguments());
//榪欓噷鐨?/SPAN>this灝辨槸鑷繁錛岃皟鐢ㄥ紩鍏ョ殑鏂規硶錛堝睘浜?/SPAN>auditable鎺ュ彛鐨勬柟娉曪級錛岃繖鏍蜂篃灝辯粰target娣誨姞浜嗘柊鐨?/SPAN>auditable鎺ュ彛銆?/SPAN>
} else {
return m.proceed();//鍏朵粬鏂規硶鐨勮皟鐢ㄣ?/SPAN>
}
}
private Date lastModifiedDate; //瀹炵幇auditable鎺ュ彛銆?/SPAN>
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
鍦?/SPAN>Spring涓紝闄や簡涓婇潰鐩存帴瀹炵幇IntroductionInterceptor鎺ュ彛涔嬪錛岃繕鍙互閫氳繃緇ф壙DelegatingIntroductionInterceptor綾誨疄鐜般傚叾涓?/SPAN>DelegatingIntroductionInterceptor緇欏嚭浜?/SPAN>IntroductionInterceptor鎺ュ彛涓殑涓や釜鏂規硶錛?/SPAN>implementsInterface錛?/SPAN>invoke錛夌殑榛樿瀹炵幇錛屼綘浠呴渶瑕佸疄鐜?/SPAN>auditable鎺ュ彛鍗沖彲銆?/SPAN>
閫氳繃璺熻釜Spring婧愪唬鐮佸彲浠ュ彂鐜幫細DelegatingIntroductionInterceptor鐨?/SPAN>implementsInterface 錛堝湪IntroductionInfoSupport綾諱腑錛夊拰invoke鏂規硶涓庝笂闈㈢殑浠g爜鐨勫艦寮忓熀鏈竴鑷淬備笅闈㈡槸鍒╃敤DelegatingIntroductionInterceptor鍐欏嚭鐨?/SPAN>AuditableMixin錛?/SPAN>
public class AuditableMixin
extends DelegatingIntroductionInterceptor implements Auditable {
private Date lastModifiedDate;
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
娉ㄦ剰鍒頒竴鐐癸細涓婇潰鐨勪袱涓?/SPAN>AuditableMixin鐨勫疄鐜伴兘浠呬粎鏄粰Target娣誨姞琛屼負錛屼絾鏄湭鏇炬敼鍙?/SPAN>Target鐨勫師鏈夎涓猴紙鍥犱負鍦?/SPAN>invoke鏂規硶鐨勫疄鐜頒腑錛岃繕鏄細杞彂緇?/SPAN>Target錛夈傚鏋滈渶瑕佹敼鍙?/SPAN>Target鐨勮涓?SPAN style="COLOR: red">錛堜緥濡傜粰Target澧炲姞lock鎺ュ彛錛屼竴鏃﹀浜?/SPAN>locked鐘舵侊紝閭d箞鍐嶈皟鐢?/SPAN>Target鐨勬柟娉曞氨浼氬嚭鐜板紓甯革級錛岃繖灝遍渶瑕佽嚜宸卞啓浠g爜淇敼invoke鏂規硶銆?/SPAN>
public class ImmutableMixin
extends DelegatingIntroductionInterceptor implements Immutable {
private boolean immutable;
public void setImmutable(boolean immutable) {
this.immutable = immutable;
}
public Object invoke(MethodInvocation mi) throws Throwable {
String name = mi.getMethod().getName();
if (immutable && name.indexOf("set") == 0) { //榪欓噷涓鏃﹀凡緇忔槸immutable浜嗭紝閭d箞灝變笉鍙互璋冪敤setXXX鏂規硶浜嗭紝榪欎篃灝辨敼鍙樹簡Target鐨勮涓猴紝鑰屼笉鏄墠闈㈢殑浠呭鍔犳帴鍙c?/SPAN>
throw new IllegalModificationException();
}
return super.invoke(mi);
}
}
Spring涓殑Introduction闇瑕佹湁鑷繁鐨?/SPAN>advisor: IntroductionAdvisor
PointCuts鐢ㄤ簬瀹氫箟鎵闇瑕佲滄嫤鎴濈殑class鍙婂叾method銆傚垎涓洪潤鎬併佸姩鎬佷袱縐?/SPAN>pointcut銆傚叾涓潤鎬?/SPAN>pointcuts浠呭拰class name, method name鐩稿叧錛屽彲浠ュ湪閰嶇疆鏂囦歡涓氳繃姝e垯琛ㄨ揪寮忚繘琛岄儴緗詫紝鍥犳瀹冧滑閮藉彲浠ュ湪榪愯鍓嶈繘琛岀‘璁ゃ傝屽姩鎬?/SPAN>pointcuts鍒欓渶瑕佽冭檻鍒版柟娉曠殑鍙傛暟錛屽湪榪愯鏃跺姩鎬佺殑紜pointcuts銆備竴鑸潵璇達紝閮芥槸鏍規嵁method鍜?/SPAN>class鐨勫悕瀛楁潵榪涜銆傚叾娑夊強鍒扮殑鎺ュ彛濡備笅瀹氫箟錛?/SPAN>
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
public interface ClassFilter {
boolean matches(Class clazz);
}
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean isRuntime();
boolean matches(Method m, Class targetClass, Object[] args);
}
涓ょ闈欐?/SPAN>pointcut鐨勫疄鐜幫細
NameMatchMethodPointcut錛氬彧鑳藉鏂規硶鍚嶈繘琛屽垽鍒?/SPAN>
RegexpMethodPointcut錛氬彲浠ュ綾誨悕銆佹柟娉曞悕浣跨敤姝e垯琛ㄨ揪寮忓垽鍒?/SPAN>
<beans>
<bean id="maidServiceTarget"
class="com.springinaction.chapter03.cleaning.MaidService"/>
<bean id="queryInterceptor" class="com.springinaction.chapter03.cleaning.QueryInterceptor"/>
<bean id="queryPointcutAdvisor"
class="org.springframework.aop.support.RegExpPointcutAdvisor">
<property name="pattern">
<value>.*get.+By.+</value>
</property>
<property name="advice">
<ref bean="queryInterceptor"/>
</property>
</bean>
<bean id="maidService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.springinaction.chapter03.cleaning.MaidService</value>
</property>
<property name="interceptorNames">
<list>
<value>queryPointcutAdvisor</value>
</list>
</property>
<property name="target">
<value ref="maidServiceTarget">
</property>
</bean>
</beans>
涓縐嶅姩鎬?/SPAN>pointcut鐨勫疄鐜幫細
ControlFlowPointcut錛氭牴鎹綋鍓嶈繍琛屾爤鐨勬儏鍐碉紝鍐沖畾褰撳墠鐨?/SPAN>advice鏄惁闇瑕佽瑙﹀彂銆傚洜涓哄畠瀹屽叏鍩轟簬榪愯鏃舵爤鐨勬儏鍐靛仛鍐崇瓥錛屾墍浠ヨ繍琛岄熷害鑲畾浼氬彉鎱€?/SPAN>
<beans>
<bean id="myServiceTarget" class="MyServiceImpl"/>
<bean id="servletInterceptor" class="MyServletInterceptor"/>
<bean id="servletPointcut" class="org.springframework.aop.support.ControlFlowPointcut">
<constructor-arg>
<value>javax.servlet.http.HttpServlet</value>
</constructor-arg>
</bean>
<bean id="servletAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice">
<ref bean="servletInterceptor"/>
</property>
<property name="pointcut">
<ref bean="servletPointcut"/>
</property>
</bean>
<bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>MyService</value>
</property>
<property name="interceptorNames">
<list>
<value>servletAdvisor</value>
</list>
</property>
<property name="target">
<value ref="myServiceTarget">
</property>
</bean>
</beans>
鍓嶉潰宸茬粡鎻愬埌錛?/SPAN>advisor鏄槸PointCut鍜?/SPAN>Advice鐨勭患鍚堜綋錛屽畬鏁存弿榪頒簡涓涓?/SPAN>advice灝嗕細鍦?/SPAN>pointcut鎵瀹氫箟鐨勪綅緗瑙﹀彂銆備篃灝辨槸璇達紝瀹冨寘鍚簡pointcut鍜?/SPAN>advice涓ら」鍐呭錛岃繖涓ら」鍐呭鍒欑敤浜庡垎鍒粰鍑?/SPAN>advice璋冪敤鎵鍙戠敓鐨勪綅緗拰鍙戠敓鐨勫唴瀹廣傚叾鎺ュ彛濡備笅錛?/SPAN>
public interface PointcutAdvisor {
Pointcut getPointcut();
Advice getAdvice();
}1銆?SPAN style="FONT: 7pt 'Times New Roman'"> around advice錛氭墍鏈?/SPAN>around advice蹇呴』瀹炵幇MethodInterceptor鎺ュ彛錛屾敞鎰?/SPAN>invoke鏂規硶鐨勫弬鏁?/SPAN>invocation鏄?/SPAN>MethodInvocation鎺ュ彛錛屽湪姝や腑鍖呭惈浜嗚澶氫俊鎭紝鍖呮嫭鍏舵墍灝佽鐨勬柟娉曞強鍏跺弬鏁幫紝AOP proxy銆?/SPAN>Jointcut絳夈?/SPAN>
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
鍦ㄥ疄鐜?/SPAN>around advice鏃訛紝鍜?/SPAN>before advice銆?/SPAN>after advice鏈夌潃涓や釜寰堝ぇ鐨勫尯鍒細1銆佸繀欏誨湪invoke鏂規硶涓皟鐢?/SPAN>MethodInvocation.proceed()錛岃繖鏍鋒墠鑳藉皢鎵鏈夎皟鐢ㄥ歡緇笅鍘伙紝璋冪敤target瀵硅薄鐨?/SPAN>method錛?/SPAN>2銆佸繀欏昏嚜宸辮繑鍥炰竴涓?/SPAN>object錛岃object鐢氳嚦鍙互涓?/SPAN>target鈥檚 method鐨勮繑鍥炲間笉涓鏍楓?/SPAN>
2銆?SPAN style="FONT: 7pt 'Times New Roman'"> before advice錛氬湪jointcut鎵ц涔嬪墠錛岃繍琛?/SPAN>advice銆傚繀欏誨疄鐜?/SPAN>MethodBeforeAdvice鎺ュ彛銆?/SPAN>
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method m, Object[] args, Object target) throws Throwable;
}
3銆?SPAN style="FONT: 7pt 'Times New Roman'"> after advice錛氬湪jointcut鎵ц涔嬪悗錛岃繍琛?/SPAN>advice銆傚繀欏誨疄鐜?/SPAN>AfterReturningAdvice鎺ュ彛銆?/SPAN>
public interface AfterReturningAdvice extends Advice {
void afterReturning(Object returnValue, Method m, Object[] args, Object target)
throws Throwable;
}
4銆?SPAN style="FONT: 7pt 'Times New Roman'"> throws advice錛氬湪jointcut鎵ц鍑虹幇寮傚父鐨勬椂鍊欙紝榪愯姝?/SPAN>advice銆傚繀欏誨疄鐜?/SPAN>ThrowsAdvice鎺ュ彛銆備絾鏄鎺ュ彛鍙槸涓涓爣璇嗘帴鍙o紝蹇呴』瀹炵幇姝ゅ瀹炵幇涓嬮潰鐨勬柟娉曪細
afterThrowing([Method], [args], [target], subclassOfThrowable)
榪炴帴鐐癸紙JoinPoint錛夛細紼嬪簭榪愯榪囩▼涓殑鏌愪釜闃舵鐐廣傚鏌愪釜鏂規硶璋冪敤錛屾垨鑰呮煇涓紓甯歌鎶涘嚭銆?/SPAN>
澶勭悊閫昏緫錛?/SPAN>Advice錛夛細鍦ㄦ煇涓繛鎺ョ偣鎵閲囩敤鐨勫鐞嗛昏緫銆傚鐞嗛昏緫鐨勮皟鐢ㄦā寮忛氬父鏈変笁縐嶏細
i. Around錛氬湪榪炴帴鐐瑰墠鍚庢彃鍏ラ澶勭悊榪囩▼鍜屽悗澶勭悊榪囩▼銆?/SPAN>
ii. Before錛氫粎鍦ㄨ繛鎺ョ偣涔嬪墠鎻掑叆棰勫鐞嗚繃紼嬨?/SPAN>
iii. After錛氬湪榪炴帴鐐逛箣鍚庤繘琛屽鐞嗐?/SPAN>
iv. Throw錛氬湪榪炴帴鐐規姏鍑哄紓甯告椂榪涜寮傚父澶勭悊銆?/SPAN>
鍒囩偣錛?/SPAN>PointCut錛夛細涓緋誨垪榪炴帴鐐圭殑闆嗗悎錛屽畠鎸囨槑澶勭悊鏂瑰紡錛?/SPAN>Advice錛夊皢鍦ㄤ綍澶勮瑙﹀彂錛屽彲浠ヤ嬌鐢ㄦ鍒欒〃杈懼紡琛ㄨ揪銆?/SPAN>
Advisor錛氭槸PointCut鍜?/SPAN>Advice鐨勭患鍚堜綋錛屽畬鏁存弿榪頒簡涓涓?/SPAN>advice灝嗕細鍦?/SPAN>pointcut鎵瀹氫箟鐨勪綅緗瑙﹀彂銆?/SPAN>
Introduction錛氫負advised object鍔犱笂涓瀹氱殑鏂規硶鎴栬呮暟鎹垚鍛樸備笌Advice灞炰簬騫跺垪鐨勬蹇碉紝浣嗘湁鐫涓瀹氱殑鍖哄埆銆?/SPAN>Advice鍙槸緇?/SPAN>target闄勫姞涓婂叾浠栫殑鍔熻兘錛屼嬌鐢ㄨ呯敋鑷沖彲浠ヨ瀵熶笉鍒幫紝浣嗘槸Introduction鍒欐坊鍔犱簡鍏朵粬鐨勫姛鑳斤紝渚嬪緇?/SPAN>target璧嬩簣浜?/SPAN>lock鍔熻兘錛岀姸鎬佺瓑銆?/SPAN>1銆?SPAN style="FONT: 7pt 'Times New Roman'">
瀵逛簬閭d簺浣跨敤鍒版湁闄愬閮ㄨ祫婧愮殑bean錛屾棤闈炲繀瑕侊紝璇峰敖閲忎嬌鍏?/SPAN>singleton2銆?SPAN style="FONT: 7pt 'Times New Roman'">
init-method鍦?/SPAN>Bean鍒涘緩寮濮嬫椂璋冪敤錛?/SPAN>destory-method鍦ㄩ攢姣佹椂璋冪敤.Spring鑷繁鎻愪緵浜?/SPAN>InitializingBean錛?/SPAN>DisposableBean.榪欎袱涓帴鍙e畬鎴愯繖涓や釜鍔熻兘錛屼竴鏃?/SPAN>Bean瀵硅薄瀹炵幇浜嗚繖涓や釜鎺ュ彛錛屽垯鏃犻渶榪涜浠諱綍閰嶇疆錛屽鍣ㄥ氨浼氬疄鐜拌繖涓や釜鍔熻兘銆傦紙褰撶劧錛岃繖涔熷氨浣垮緱浣犵殑搴旂敤鍜?/SPAN>Spring API鎹嗙粦鍒頒簡涓璧鳳級3銆?SPAN style="FONT: 7pt 'Times New Roman'">
Innner Bean錛氳繖鏍風殑閰嶇疆浣垮緱inner bean鍙兘琚?/SPAN>wrapper bean鎵寮曠敤銆傝繖鐐瑰湪AOP涓挨鍏舵湁鐢細BeanFactory鍙兘璁塊棶AOProxy錛岃屼笉鑳界洿鎺ュ緱鍒?/SPAN>AOProxy鎵灝佽鐨?/SPAN>target object銆?/SPAN>4銆?SPAN style="FONT: 7pt 'Times New Roman'">
闆嗗悎鍏冪礌<list> 脿java.awt.List, arrays
<set> 脿java.awt.Set
<map> 脿java.awt.Map
<props> 脿java.awt.Properties
5銆?SPAN style="FONT: 7pt 'Times New Roman'">
璁劇疆絀哄鹼細<property name="foo"><null/><property>6銆?SPAN style="FONT: 7pt 'Times New Roman'">
鏋勯犲嚱鏁版敞鍏ワ細鐢ㄤ簬閭d簺蹇呴』鐨勩?/SPAN>final鐨勫弬鏁般傚鏋滄瀯閫犲嚱鏁扮殑鍙傛暟鍙兘寮曡搗鍐茬獊錛屽彲浠ュ湪閰嶇疆鏂囦歡涓粰鍚勫弬鏁板姞涓?/SPAN>type銆?/SPAN>7銆?SPAN style="FONT: 7pt 'Times New Roman'">
autowiring錛氬畠浼氬甫鏉ヤ竴瀹氱殑闂錛屽洜涓烘棤璁哄浣?/SPAN>autowiring錛岄兘鏃犳硶淇濊瘉鍏剁粨鏋滀竴瀹氭紜紝寰堝彲鑳戒細鍑虹幇璁稿涓庨鏈熶笉涓鑷寸殑鍦版柟銆?/SPAN>鍦?/SPAN>BeanFactory涓紝鎵鏈夌殑bean瀵硅薄鐨勫垱寤洪兘鏄?/SPAN>lazy鐨勶紝鍖呮嫭閭d簺singleton bean銆傚彧鏈?/SPAN>javabean瀵硅薄蹇呴』琚嬌鐢ㄧ殑鏃跺欙紝鎵嶄細鍒涘緩璇ュ璞★紝鎵嶄細姝e紡鐨勮В鏋愮浉搴旂殑xml鏍囪錛岃В鏋愯bean鐨?/SPAN>property絳夈備絾鏄湪ApplicationContext錛屽畠鍙互棰勫厛杞藉叆sigleton bean錛岃屼笉鏄洿鍒頒嬌鐢ㄦ椂鎵嶅垱寤恒?/SPAN>
BeanFactory鏈甯哥敤鐨勫疄鐜版槸XmlBeanFactory錛岃澆鍏モ滃畾浣?/SPAN>xml鈥濇枃浠訛細
BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
ApplicationContext鏈変笁縐嶅疄鐜幫細ClassPathXmlApplicationContext錛?/SPAN>FileSystemXmlApplicationContext錛?/SPAN>XmlWebApplicationContext銆傚叾涓墠涓よ呬篃鏄熀浜庤礬寰勭殑錛屽拰BeanFactory鐨?/SPAN>xml鏂囦歡瀹氫綅鏂瑰紡涓鑷淬?/SPAN>
ApplicationContext context =new FileSystemXmlApplicationContext("c:/foo.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");
BeanFactory綆$悊Bean瀵硅薄鐨勭敓鍛藉懆鏈燂細
1銆?SPAN style="FONT: 7pt 'Times New Roman'">
浣跨敤鏋勯犲嚱鏁板垱寤?/SPAN>Bean瀵硅薄2銆?SPAN style="FONT: 7pt 'Times New Roman'">
Bean瀵硅薄autowire琚墽琛?/SPAN>3銆?SPAN style="FONT: 7pt 'Times New Roman'">
Bean瀵硅薄璋冪敤鍚勯」setXXX鏂規硶4銆?SPAN style="FONT: 7pt 'Times New Roman'">
濡傛灉璇?/SPAN>Bean瀹炵幇浜?/SPAN>BeanNameAware鎺ュ彛錛屽垯璋冪敤璇ュ璞$殑setBeanName()鏂規硶錛岃緗叾ID錛堝凡緇忓湪xml閰嶇疆鏂囦歡涓啓濂戒簡錛?/SPAN>5銆?SPAN style="FONT: 7pt 'Times New Roman'">
濡傛灉璇?/SPAN>Bean瀹炵幇浜?/SPAN>BeanFactoryAware鎺ュ彛錛屽垯璋冪敤璇ュ璞$殑setBeanFactory()鏂規硶錛屼紶鍏?/SPAN>BeanFactory瀵硅薄鑷韓6銆?SPAN style="FONT: 7pt 'Times New Roman'">
濡傛灉宸茬粡閰嶇疆浜?/SPAN>BeanPostProcessor錛岄偅涔堣皟鐢?/SPAN>BeanPostProcessors鐨?/SPAN>pre-ProcessBeforeInitialization()鏂規硶錛屽璇ean瀵硅薄榪涜澶勭悊錛?/SPAN>
7銆?SPAN style="FONT: 7pt 'Times New Roman'">
濡傛灉璇?/SPAN>bean鑷畾涔変簡init()鏂規硶錛岄偅涔堣皟鐢ㄦ鏂規硶8銆?SPAN style="FONT: 7pt 'Times New Roman'"> 濡傛灉宸茬粡閰嶇疆浜?/SPAN>BeanPostProcessor
錛岄偅涔堣皟鐢ㄨBeanPostProcessors鐨?/SPAN>postProcessBeforeInitialization()鏂規硶錛屽璇ean瀵硅薄榪涜澶勭悊
9銆?SPAN style="FONT: 7pt 'Times New Roman'">
姝e父浣跨敤10銆?SPAN style="FONT: 7pt 'Times New Roman'">
緋葷粺閿姣侊紝濡傛灉璇?/SPAN>bean瀵硅薄瀹炵幇浜?/SPAN>DisposableBean鎺ュ彛錛屽垯璋冪敤鍏?/SPAN>destory()鏂規硶錛?/SPAN>11銆?SPAN style="FONT: 7pt 'Times New Roman'">
鏈鍚庤皟鐢ㄧ敤鎴峰湪閰嶇疆鏂囦歡涓紪鍐欑殑destroy-method
鏁翠釜Web搴旂敤鍒嗕負鍥涢儴鍒?/SPAN>
1銆?SPAN style="FONT: 7pt 'Times New Roman'"> 鍗曠嫭鐨?/SPAN>DAO錛岃礋璐f暟鎹闂紝鎵цCUID(create, update, insert ,delete)錛?SPAN style="COLOR: red">瀹屾垚O/R鏄犲皠銆備笉娑夊強浠諱綍鐨勫叾浠栭昏緫錛屼粎鎵ц榪欎互涓婄殑鎿嶄綔錛屽鏋滄湁鍞竴鎬ф鏌ャ佷簨鍔′篃涓嶉渶瑕佸仛銆傦紙鍙互鍦ㄦ暟鎹簱绔姞涓浜?/SPAN>trigger,constraint錛夈?SPAN style="COLOR: red">璇ュ眰闇瑕佸畾涔?/SPAN>DAO鎺ュ彛錛?/SPAN>DAO瀹炵幇(hibernate錛?/SPAN>ibaits錛?/SPAN>JDBC絳?/SPAN>)銆?/SPAN>
2銆?SPAN style="FONT: 7pt 'Times New Roman'"> 綆鍗曠殑Logic Object錛?/SPAN>Java Bean錛夛紝data field+setter+getter+Other Logic錛屽彲浠ュ皢涓浜涘叡鏈夌殑鎿嶄綔鎻愬彇鍒扮埗綾諱腑錛屽噺灝戜唬鐮併?/SPAN>
3銆?SPAN style="FONT: 7pt 'Times New Roman'"> Business Sevice錛屽疄鐜頒笟鍔¢昏緫錛屽湪姝や嬌鐢?/SPAN>DAO鍜?/SPAN>Logic Object瀹屾垚涓氬姟鎿嶄綔銆?/SPAN>榪欓噷褰撲嬌鐢ㄥ埌DAO鏃訛紝鍙渶瑕?/SPAN>IOC娉ㄥ叆錛岀湡瀹炲璞$敱澶栫晫錛?/SPAN>Web瀹瑰櫒璋冪敤Spring瀹瑰櫒錛夋敞鍏ャ?/SPAN>
4銆?SPAN style="FONT: 7pt 'Times New Roman'"> 緙栧啓Action錛屽皢鐢ㄦ埛鐣岄潰鐨勬搷浣滄槧灝勫埌Busibess service銆?/SPAN>
浣跨敤Spring MVC鐨勫叿浣撻厤緗細
1銆?/SPAN>鍦?/SPAN>web.xml涓?/SPAN>, 澧炲姞dispatcher鐨勫畾涔夛紝閰嶇疆濂?/SPAN>URL Mapping鍒嗗彂鐢ㄦ埛璋冪敤銆?/SPAN>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
緙栧啓鐩稿簲鐨?/SPAN>action-servlet.xml
2銆佸鏋滀嬌鐢ㄤ簡澶氫釜context鏂囦歡錛?/SPAN>Spring鐨勯厤緗枃浠訛級錛屽垯闇瑕佸湪Web.xml涓繘琛岄厤緗紝鍏蜂綋濡備笅錛?/SPAN>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext1.xml
/WEB-INF/applicationContext2.xml
</param-value>
</context-param>
鍏朵綅緗湪鈥?/SPAN>sitemesh filter鈥濅箣鍚庯紝浣嗘槸鍦?/SPAN>filter-mapping涔嬪墠銆?/SPAN>
3. 澧炲姞ContextLoaderListener.
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
瀵圭収浜哠pring in action,閭d釜璁茬殑鏇村ソ鍝︺備粠spring鐨勫熀紜寮濮嬭璧鳳紝寰堜笉閿欍?/P>
java浠g爜: |
<bean id="someObjectProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>ISomeInterface</value> </property> <property name="target"> <ref bean="someObject"/> </property> <property name="interceptorNames"> <list> <value>lockMixinAdvisor</value> </list> </property> </bean> |
java浠g爜: |
<bean id="someObjectProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> |
java浠g爜: |
ISomeInterface someObjectProxy = (ISomeInterface) context .getBean("someObjectProxy"); |
娉ㄦ剰錛岃繖閲岃繑鍥炵殑鏄疘SomeInterface 錛岃屼笖榪欎釜someObjectProxy 瀵硅薄宸茬粡鍏鋒湁浜咺Lock錛婭SomeInterface 鐨勫姛鑳斤紝騫朵笖鍦ㄨ涓鴻〃鐜扮殑瀹屽叏鍜孖SomeInterface 涓鑷淬?
濡傛灉Spring鐨勪唬鐮佹槸棰勭紪璇戠殑錛岄偅鍙互浜х敓stub涔嬬被鐨勶紝鍙繖閲屾槸鎬庝箞瀹炵幇鐨勶紝鎸鴻浜哄鎬摝錛岃皝鑳借В閲婁竴涓嬩箞錛?
絳旀 錛?http://www.javajia.com/article.php?id=919
鍙槸鍦ㄨ繖涓婇潰鍐嶅皝瑁呯殑瀹岀編緗簡錛屽ソ濂界爺絀禿ynamic proxy鐨勫疄鐜板惂銆?/P>
姝ゅ錛岃繕鏈夎繖涓孌靛摝 錛氾級
AOP鐨勪綔鐢ㄥ彲浠ョ畝鍗曞涓嬫墍璇達細鈥滃湪涓涓粍浠剁殑鍓嶅悗鍔犱笂涓浜涘浐瀹氱殑鍐呭銆傗?鎶涘紑AOP涓嶈錛屾垜浠嚜宸卞鏋滄兂瑕佸啓榪欎笢瑗匡紝鏃犻潪涓ょ鏂瑰紡錛屼竴涓槸proxy瀹炵幇錛岀劧鍚庡湪proxy鐨勫墠鍚庢坊鍔犲唴瀹癸紱榪樻湁涓縐嶅氨鏄痶emplate瀹炵幇銆?
鎵浠ュ湪鎴戠湅鏉ワ紝鏁版嵁搴撳眰鐨勬ā鏉垮叾瀹炰篃綆楁槸涓縐嶁淎OP鈥濄?涓嶇煡閬撴湁娌′漢瀵規鏈変簺鎰忚鍜岃瘎榪幫紵
6銆侀潪甯稿ソ鐨勪竴涓姛鑳斤紝鍦⊿pring Beans閭d釜紿楀彛涓坊鍔犲ソ浣犵殑Spring閰嶇疆鏂囦歡涔嬪悗錛屽湪鍏朵腑鍙抽敭浣犵殑閰嶇疆鏂囦歡錛岄夋嫨鈥渟how graph鈥濓紝it's such a wonderful function~~~~
鍦ㄧ嚎瀹夎鍦板潃錛? http://springframework.sourceforge.net/spring-ide/eclipse/updatesite/.
娉ㄦ剰鍝︼紝鍦ㄥ畨瑁呯殑鏃跺欙紝涓瀹氳閫夆淪pring framework鈥?鐒跺悗鎵嶅彲浠ヨ鈥淪pring IDE鈥?灝辨槸Beans Configuration Support鍟︺?