??xml version="1.0" encoding="utf-8" standalone="yes"?>18禁亚洲深夜福利人口,亚洲欧洲精品视频在线观看,亚洲精品123区在线观看http://m.tkk7.com/wyxdeniro/category/27586.htmlƲؓ(f)怽(jng)龙象Q必先做众生牛马zh-cnTue, 24 Nov 2009 08:33:19 GMTTue, 24 Nov 2009 08:33:19 GMT60Spring学习(fn)W记(十六)-----Spring in Action http://m.tkk7.com/wyxdeniro/archive/2009/11/22/303208.html王永?/dc:creator>王永?/author>Sun, 22 Nov 2009 03:43:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/22/303208.htmlhttp://m.tkk7.com/wyxdeniro/comments/303208.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/22/303208.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/303208.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/303208.html    在Y件中Q要么全有要么全无的操作成ؓ(f)事务。事务允怽把几个操作组成一个单一的工作单元,q个工作单元要么全部发生要么全部不发生。如果每件事都顺利,那么q个事务是成功的。但是如果Q何一件事情出错的话,那么已经发生的行为就被清除掉Q就像什么事情都没发生一栗?br />     Spring对事务管理有丰富的支持,E序控制的和声明式的?br />     原子?Atomic):事务׃个或多个行ؓ(f)l定在一L(fng)成,好像是一个单独工作单元。原子性确保在十五中的所有操作要么都发生Q要么都不发生?br />     一致?Consistent):一旦一个事务结束了(不管成功p|)Q系l所处的状态和它的业务规则是一致的。就是说数据应当不会(x)被破坏?br />     隔离?Isolated):事务应该允许多个用户操作同一数据Q一个用L(fng)操作不会(x)和其他用L(fng)操作相؜淆。因此,事务必须是互盔RȝQ防止ƈ发读写同一数据的情况发生?br />     持久?Durable):一旦事务完成,事务的结果应该持久化Q这样不什么样的系l崩溃,他们都将q免于难?br />  
    Spring对程序控制事务管理的支持和EJB的有很大不同。EJB的事务管理和JTA密不可分Q和EJB不同的是QSpring使用了一U回调机Ӟ把真实的事务实现从事务代码中抽象出来。选择E序控制事务理q是声明式事务管理,很大E度上是在细_度控制与简便操作之间做出决定。当你在代码中编写事务时Q你能精控制事务的边界Q在你希望的地方_的开始和l束。典型的情况下,你不需要程序控制事务所提供的细_度控制Q你?x)选择在上下文定义文g中声明你的事务?/p>

    Spring对声明式事务理的支持是通过它的AOP框架实现的。这样做是非常自然的Q因Z务是pȝU的Q凌驾于应用的主要功能之上的?/p>

    在Spring里,事务属性是对事务策略如何应用到Ҏ(gu)的描q。这个描q包括:(x)传播行ؓ(f)、隔ȝ别、只LC、事务超旉?br />     传播行ؓ(f)Q?br />     PROPAGATION_MANDATORY:表示该方法必运行在一个事务中。如果当前事务不存在Q将抛出一个异常?br />     PROPAGATION_NESTED:表示如果当前已经存在一个事务,则该Ҏ(gu)应当q行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交或回滚。如果当前事务不存在Q那么它看v来和PROPAGATION_REQUIRED没有两样?br />     PROPAGATION_NEVER:表示当前的方法不应该q行在一个事务上下文中。如果当前存在一个事务,则会(x)抛出一个异常?br />     PROPAGATION_NOT_SUPPORTED:表示该方法不应在事务中运行。如果一个现有的事务正在q行中,它将在该Ҏ(gu)的运行期间被挂v?br />     PROPAGATION_REQUIRED:表示当前Ҏ(gu)必须q行在一个事务中。如果一个现有的事务正在q行中,该方法将q行在这个事务中。否则的话,要开始一个新的事务?br />     PROPAGATION_REQUIRES_NEW:表示当前Ҏ(gu)必须q行在它自己的事务里。它?yu)启动一个新的事务。如果有事务q行的话Q将在这个方法运行期间被挂v?br />     PROPAGATION_SUPPORTS:表示当前Ҏ(gu)不需要事务处理环境,但如果有一个事务已l在q行的话Q这个方法也可以在这个事务里q行?/p>

   传播规则回答了一个问题:(x)是新的事务是否要被启动或是被挂P或者方法是否要在事务环境中q行?/p>

   隔离U别Q在一个典型的应用中,多个事务q发q行Q经怼(x)操作同一个数据来完成它们的Q务。ƈ发,虽然是必ȝQ但?x)导致下面问题?x)
1、脏读:(x)脏读发生在一个事务读取了被另一个事务改写但q未提交的数据时。如果这些改变在E后被回滚,那么W一个事务读取的数据是无效的?br /> 2、不可重复读Q不可重复读发生在一个事务执行相同的查询2ơ或2ơ以上,但每一ơ查询结果都不同时。这通常是由于另一个ƈ发事务在2ơ查询之间更C数据?br /> 3、读:(x)q读和不可重复读怼。当一个事务读取几行纪录后Q另一个ƈ发事务插入一些记录,q读发生了。隔ȝ别有如下几个Q?br /> ISOLATION_DEFAULT:使用后端数据库默认的隔离U别
ISOLATION_READ_UNCOMMITTED:允许你读取还未提交的改变了的数据Q可能导致脏诅R诅R不可重复读
ISOLATION_READ_COMMITTED:允许在ƈ发事务已l提交后d。可防止脏读Q但q读和不可重复读仍可能发生?br /> ISOLATION_REPEATABLE_READ:对相同字D늚多次d的结果是一致的Q除非数据被事务本n改变。可防止脏读和不可重复读Q但q读仍可能发生?br /> ISOLATION_SERIALIZABLE:完全服从ACID的隔ȝ别,保不发生脏诅R不可重复读和诅R这在所有隔ȝ别中也是最慢的?/p>

    只读Q如果一个事务只对后端是据库执行L作,数据库就可能利用事务只读的特性,使用某些优化措施。通过声明一个事务ؓ(f)只读Q你q了后端数据库一个机?x),来应用那些它认?f)合适的优化措施。因为只ȝ优化措施是在事务启动时由后端数据库实施的Q所以,只有那些具有可能启动新事务的传播行为的Ҏ(gu)的事务标记成只读才有意义(PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED) TransactionProxyFactoryBean参照一个方法的事务属性,军_如何在那个方法上执行事务{略?br />

<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        
<property name="jndiName">
            
<value>java:comp/env/jdbc/myDatasource</value>
        
</property>
    
</bean>
    
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
<property name="dataSource">
            
<ref bean="dataSource"/>
        
</property>
    
</bean>
    
<!-- q个对象有一个gؓ(f)courseService的id.当应用从应用上下文里h一个courseServiceӞ它将得到一个被
    TransactionProxyFactoryBean包裹的实例?nbsp;
-->
    
<bean id="courseService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        
<!-- 代理所实现的接?nbsp;-->
        
<property name="proxyInterfaces">
            
<list>
                
<value>
                    com.springinaction.training.service.CourseService
                
</value>
            
</list>
        
</property>
        
<!-- 被代理的对象 -->
        
<property name="target">
            
<ref bean="courseServiceTarget"/>
        
</property>
        
<!-- 事务理?nbsp;-->
        
<property name="transactionManager">
            
<ref bean="transactionManager"/>
        
</property>
        
<!-- 事务的属性源 -->
        
<property name="transactionAttributeSource">
            
<ref bean="transactionAttributeSource"/>
        
</property>
    
</bean>
    
<!-- 要知道尽可以改变MatchAlwaysTransactionAttributeSource的事务属性参敎ͼ但它Lq回相同的事务属性,?br />     不关心参与交易的哪一个方法。当你有一个相对简单的应用Q把同样的事务策略应用到所有方法都没问题时Q用MatchAlwaysT
    ransactionAttributeSourceq当好。但是,在那些更为复杂的应用中,你很可能需要对不同的方法应用不同的事务{略。在那样
    情况下,你需要在应用何种{略的问题上做更多精的控制?nbsp;
-->
    
<bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
        
<property name="transactionAttribute">
            
<ref bean="myTransactionAttribute"/>
        
</property>
    
</bean>
    
<!-- 定义事务{略 -->
    
<bean id="myTransactionAttribute" class="org.springframework.transaction.interceptor.DefaultTransactionAttribute">
        
<!-- 传播行ؓ(f) -->
        
<property name="propagationBehaviorName">
            
<value>PROPAGATION_REQUIRES_NEW</value>
        
</property>
        
<!-- 隔离U别 -->
        
<property name="isolationLevelName">
            
<value>ISOLATION_REPEATABLE_READ</value>
        
</property>
    
</bean>
</beans>

 

除了transactionAttributeSource对象l入到TransactionProxyFactoryBean的transactionAttributeSource属性中外,q有一U简单的Ҏ(gu)。发展到现在QTransactionProxyFactoryBean也有一个transactionAttributes属性ؓ(f)transactionProperties.

<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        
<property name="jndiName">
            
<value>java:comp/env/jdbc/myDatasource</value>
        
</property>
    
</bean>
    
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
<property name="dataSource">
            
<ref bean="dataSource"/>
        
</property>
    
</bean>
    
<!-- q个对象有一个gؓ(f)courseService的id.当应用从应用上下文里h一个courseServiceӞ它将得到一个被
    TransactionProxyFactoryBean包裹的实例?nbsp;
-->
    
<bean id="courseService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        
<!-- 代理所实现的接?nbsp;-->
        
<property name="proxyInterfaces">
            
<list>
                
<value>
                    com.springinaction.training.service.CourseService
                
</value>
            
</list>
        
</property>
        
<!-- 被代理的对象 -->
        
<property name="target">
            
<ref bean="courseServiceTarget"/>
        
</property>
        
<!-- 事务理?nbsp;-->
        
<property name="transactionManager">
            
<ref bean="transactionManager"/>
        
</property>
        
<!-- 事务的属性源 -->
        
<property name="transactionAttributeSource">
            
<ref bean="transactionAttributeSource"/>
        
</property>
    
</bean>
    
<!-- NameMatchTransactionAttributeSource的properties属性把Ҏ(gu)名映到事务属性描q器上。注意CourseException
    用一个负h记。异常可以用负号或正h讎ͼ当负号异常抛出时Q将触发回滚;相反的,正号异常表示事务仍可提交Q即使这个异常抛?nbsp;
-->
    
<bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
        
<property name="properties">
            
<props>
                
<prop key="enrollStudentInCourse">
                    PROPAGATION_REQUIRES_NEW,ISOLATION_REPEATABLE_READ,readOnly,
                    -CourseException
                
</prop>
                
<!-- q可以用通配W?nbsp;-->
                
<prop key="get*">
                    PROPAGATION_SUPPORTS
                
</prop>
            
</props>
        
</property>
    
</bean>
</beans>

 

 



]]>
Spring学习(fn)W记(十五)-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302347.html王永?/dc:creator>王永?/author>Sat, 14 Nov 2009 07:59:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302347.htmlhttp://m.tkk7.com/wyxdeniro/comments/302347.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302347.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/302347.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/302347.html
<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        
<property name="jndiName">
            
<value>java:comp/env/jdbc/trainingDatasource</value>
        
</property>
    
</bean>
    
<!-- 理Hibernate资源Q在应用的整个生命周期里Q你只要保存一个SessionFactory实例可以了?/span>-->
    
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        
<!-- 先要知道q接哪个数据?nbsp;-->
        
<property name="dataSource">
            
<ref bean="dataSource"/>
        
</property>
        
<!-- Hibernate本n有数十个属性,通过q些属性你可以控制它的行为。当在Spring之外使用Hibernage的时候,
        Hibernate在应用的class path下的某个地方L一个名叫hibernate.properties的文Ӟq用它来q行配置?br />         然而,用Spring׃需要在一个独立的属性文仉理q些配置?nbsp;
-->
        
<property name="hibernateProperties">
            
<props>
                
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
            
</props>
        
</property>
        
<!-- 同样Q你也要告诉Spring从哪里读取Hibernate.hbm.xml映射文g -->
        
<property name="mappingResources">
            
<list>
                
<value>Student.hbm.xml</value>
            
</list>
        
</property>
        
<!-- q有一U简单的Ҏ(gu)讄映射文g资源,你可以用你应用的class path下的一个子路径来配|?br />         mappingDirectoryLocation属性,spring找到这个\径下的每?.hbm.xml文gQ来配置SessionFactory -->
        
<property name="mappingDirectoryLocations">
            
<list>
                
<value>classpath:/com/springinaction/training/model</value>
            
</list>
        
</property>
    
</bean>
    
<!-- 如果把这个模版对象织入到一个个DAOBean中显得很ȝ的时候,可以使用Spring自动q接功能来将模版对象隐士的织入到
    DAObean. 
-->
    
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        
<property name="sessionFactory">
            
<ref bean="sessionFactory"/>
        
</property>
    
</bean>
    
</beans>


]]>
Spring学习(fn)W记(十四)-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302340.html王永?/dc:creator>王永?/author>Sat, 14 Nov 2009 07:21:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302340.htmlhttp://m.tkk7.com/wyxdeniro/comments/302340.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/14/302340.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/302340.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/302340.html调用存储q程Q?br /> Spring通过实现CallableStatementCallback来支持存储过E。假定有个存储过E的名字是ARCHIVE_STUDENTS,执行代码如下Q?br />

package com.testproject.spring.datasource;

import java.sql.CallableStatement;
import java.sql.SQLException;

import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.JdbcTemplate;
/*
 * Z让JdbcTemplate工作Q它所需要的Q只是一个DataSource实例?br />  
*/

public class StudentDaoImpl implements StudentDao {
    
private JdbcTemplate jdbcTemplate;
    
    
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        
this.jdbcTemplate = jdbcTemplate;
    }

    
/**
     * 调用存储q程Q通过CallableStatementCallback来实?br />      
*/

    
public void archiveStudentData(){
        CallableStatementCallback cb 
= new CallableStatementCallback(){
            
public Object doInCallableStatement(CallableStatement cs)throws SQLException{
                cs.execute();
                
return null;
            }

        }
;
        jdbcTemplate.execute(
"{ARCHIVE_STUDENTS}",cb);
    }

}


把操作创建成对象Q?br />

插入Q?br />

package com.testproject.spring.datasource;

import java.sql.Types;

import javax.sql.DataSource;

import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.SqlUpdate;
/**
 * Spring提供了一U真正把数据库操作徏模成对象的方法,q样在的代码和直接JDBC之间又加了一个绝~层?br />  * 首先Q这些数据库操作对象是线E安全的Q意味着对于每个数据库操作,你只需创徏一个实例?br />  * 其次QQ何数据库操作对象必须在运行前先编译一下,q样p对象知道什么时候可以预备statement,以便在稍后能执行它们?br />  * 使用Q?br />  * private InsertPerson insertPerson;
 * public int insertPerson(Person person){
 *     return insertPerson.insert(person);
 * }
 *
 
*/

public class InsertPerson extends SqlUpdate {
    
public InsertPerson(DataSource ds){
        
//首先要给sqlUpdate提供一个DataSource,用来创徏JdbcTemplate
        setDataSource(ds);
        setSql(
"insert into person(id,firstName,lastName) values(?,?,?)");
        
//其次Q我们需要ؓ(f)statement中的每个参数调用q个Ҏ(gu)Q顺序也是很重要?/span>
        declareParameter(new SqlParameter(Types.NUMERIC));
        declareParameter(
new SqlParameter(Types.VARCHAR));
        declareParameter(
new SqlParameter(Types.VARCHAR));
        
//最后编译它Q每个数据库操作对象必须在它被用之前编译好?/span>
        compile();
    }

    
public int insert(Person person){
        Object[] params 
= new Object[]{
                person.getId(),
                person.getFirstName(),
                person.getLastName()
        }
;
        
return update(params);
    }

}

查询Q?br />

package com.testproject.spring.datasource;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import javax.sql.DataSource;

import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;

/**
 * 使用Q?br />  * private PersonByIdQuery personByIdQuery;
 * public person getPerson(Integer id){
 *     Object[] params = new Object[]{id};
 *  return (Person)personByIdQuery.execute(params).get(0);
 * }
 *
 
*/

public class PersonByIdQuery extends MappingSqlQuery {
    
    
public PersonByIdQuery(DataSource ds){
        
super(ds,"select id,first_name,last_name from person where id=?");
        declareParameter(
new SqlParameter("id",Types.INTEGER));
        compile();
    }

    
    
protected Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
        Person person 
= new Person();
        person.setId((Integer)rs.getObject(
"id"));
        person.setFirstName(rs.getString(
"first_name"));
        person.setLastName(rs.getString(
"last_name"));
        
return person;
    }


}

 



]]>
Spring学习(fn)W记(十三)-----Spring in Action http://m.tkk7.com/wyxdeniro/archive/2009/11/12/302140.html王永?/dc:creator>王永?/author>Thu, 12 Nov 2009 11:46:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/12/302140.htmlhttp://m.tkk7.com/wyxdeniro/comments/302140.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/12/302140.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/302140.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/302140.html阅读全文

]]>
Spring学习(fn)W记(十二)-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301455.html王永?/dc:creator>王永?/author>Fri, 06 Nov 2009 08:00:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301455.htmlhttp://m.tkk7.com/wyxdeniro/comments/301455.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301455.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/301455.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/301455.html
BeanNameAutoProxyCreateQؓ(f)匚w一pd名字的Bean自动创徏代理。它也允许在名字?端进行通配W的匚w?br />
<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="performanceThresholdInterceptor" class="com.wyq.spring.common.aopinstance.autoproxy.PerformanceThresholdInterceptor">
        
<constructor-arg>
            
<value>5000</value>
        
</constructor-arg>
    
</bean>
    
<!-- 
        如果Bean是一个Advisor或拦截器Q它?yu)应用到代理对象的所有方法上。如果是通知的话QAdvisor切入?br />         ?x)根据不同Bean通知应用C同的地方?br />      
-->
    
<bean id="performanceThresholdProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        
<property name="beanNames">
            
<list>
                
<value>*Service</value>
            
</list>
        
</property>
        
<property name="interceptorNames">
            
<value>performanceThresholdInterceptor</value>
        
</property>
    
</bean>
</beans>
更强大的自动代理创徏器是DefaultAdvisorAutoProxyCreator.当ApplicationContextd所有Bean的配|信息后QDefaultAdvisorAutoProxyCreator扫描上下文Q寻找所有的Advisor.它将q些Advisor应用到所有符合Advisor切入点的Bean中?br />
<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="performanceThresholdInterceptor" class="com.wyq.spring.common.aopinstance.autoproxy.PerformanceThresholdInterceptor">
        
<constructor-arg>
            
<value>5000</value>
        
</constructor-arg>
    
</bean>
    
<!-- 
        一个Advisor是一个切入点和一个通知的结合体。不用显C的Advisor与其他东西结合,现在只要单的定义他们Q然后让他们自动
        应用C们匹配的地方。这h耦合Bean以及(qing)他们的通知实C。你只管写好你的BeanQ写好你的通知Q让容器来充当媒婆?br />      
-->
    
<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        
<property name="advice">
            
<bean class="com.wyq.spring.common.aopinstance.autoproxy.PerformanceThresholdInterceptor"></bean>
        
</property>
        
<property name="pattern">
            
<value>.+Service\..+</value>
        
</property>
    
</bean>
    
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    
</bean>
</beans>



]]>
Spring学习(fn)W记(十一)-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301450.html王永?/dc:creator>王永?/author>Fri, 06 Nov 2009 07:35:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301450.htmlhttp://m.tkk7.com/wyxdeniro/comments/301450.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301450.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/301450.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/301450.html Spring通过一个特D的Ҏ(gu)拦截器接口IntroductionMethodInterceptor来实现引入。这个接口添加一个方法:(x)
boolean implementsInterface(Class intf);
如果IntroductionMethodInterceptor是ؓ(f)了实现指定接口,那么Ҏ(gu)implementsInterface应该q回true.是_(d)调用q个接口声明的方法的M调用被委派lIntroductionMethodInterceptor的invoke()Ҏ(gu).invoke()Ҏ(gu)负责实现q个Ҏ(gu)Q不能调用MethodInvocation.proceed().他引入了新的接口Q调用目标对象是没有用的?br />
Spring提供了一个方便的cL处理我们的大多数应用QDelegatingintroductionInterceptor.代码Q?br />
package com.wyq.spring.base.aopinstance;

import java.util.Date;

/** 
 * 
@author 作?nbsp;
 * 
@version 创徏旉Q?009-11-6 下午02:58:21 
 * c说?nbsp;
 
*/
public interface Auditable {
    
void setLastModifiedDate(Date date);
    Date getLastModifiedDate();
}

package com.wyq.spring.base.aopinstance;

import java.util.Date;

import org.springframework.aop.support.DelegatingIntroductionInterceptor;

/** 
 * 
@author 作?nbsp;
 * 
@version 创徏旉Q?009-11-6 下午03:00:06 
 * c说?nbsp;
 
*/
public class AuditableMixin extends DelegatingIntroductionInterceptor implements
        Auditable {
    
private Date lastModifiedDate;
    
/*
     * 注意我们不用实现invoke()Ҏ(gu)?DelegatingIntroductionInterceptor为我们实Cq?br />      * 个方法。DelegatingIntroductionInterceptor也要实现你的混合cL露的MҎ(gu)Qƈ且将
     * M对这些方法的调用委托l这个؜合类。因为我们的cdCAuditable,对这个接口的Ҏ(gu)?br />      * 所有调用都调用我们的拦截器。Q何其他方法将委托l目标对象?br />      
*/
    
public Date getLastModifiedDate() {
        
return lastModifiedDate;
    }

    
public void setLastModifiedDate(Date lastModifiedDate) {
        
this.lastModifiedDate = lastModifiedDate;
    }

}

创徏一个引入Advisor:
因ؓ(f)引入通知只应用在cdơ上Q所以引入有他们自己的Advisor:IntroductionAdvisor.Spring也提供了一个适合大多数情늚~省实现。它的名字叫做DefaultIntroductionAdvisor.
BeanFactory对象是一个负责创建其他JavaBean的JavaBean.我们的ProxyFactoryBean创徏代理对象。和其他JavaBean一P它有控制行ؓ(f)的属性?br />
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<!-- 创徏一个目标对?nbsp;-->
    
<bean id="courseTarget" class="com.springinaction.training.model.Course"></bean>
    
<!-- 创徏一个引?nbsp;-->
    
<bean id="auditableMixin" class="com.springinaction.training.advice.AuditableMixin"></bean>
    
<!-- 创徏一个引入通知 -->
    
<bean id="auditableAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
        
<constructor-arg>
            
<ref bean="auditableMixin"/>
        
</constructor-arg>
    
</bean>
    
<!-- 创徏一个代?
        
ProxyFactoryBean的属?br />          target:代理的目标对?br />          proxyinterfaces:代理应该实现的接口列?br />          interceptorNames:需要应用到目标对象上的通知Bean的名字,可以是拦截器、Advisor或者其他通知cd的名字?br />          singleton:在每ơ抵用getBeanӞ工厂是否q回的是同一个代理实例。如果是有状态通知Q应该设|ؓ(f)false.
         aopProxyFactory:通常不需要用这个属性?br />          ProxyTargetClassQ是否代理目标类Q而不是接口类?br />       -->
    
<bean id="course" class="org.springframework.aop.framework.ProxyFactoryBean">
        
<property name="proxyTargetClass">
            
<value>true</value>
        
</property>
        
<property name="singleton">
            
<value>false</value>
        
</property>
        
<property name="proxyInterfaces">
            
<value>com.springinaction.training.advice.Auditable</value>
        
</property>
        
<property name="interceptorNames">
            
<ref bean="auditableAdvisor"/>
        
</property>
        
<property name="target">
            
<ref bean="courseTarget"/>
        
</property>
    
</bean>
</beans>



]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301437.html王永?/dc:creator>王永?/author>Fri, 06 Nov 2009 06:48:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301437.htmlhttp://m.tkk7.com/wyxdeniro/comments/301437.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301437.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/301437.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/301437.html 。只有当所有切入点都匹配时交叉集合才匹配,M一个切入点匚w都会(x)使合q合匹配。ؓ(f)了对2个Pointcut对象q行合ƈQ必M用PointcutscR例如:(x)
Pointcut union = Pointcuts.union(pointcut1,pointcut2);
q种方式的一个缺Ҏ(gu)它需要通过~码来实现?br />
package com.wyq.spring.base.aopinstance;

import java.util.List;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.Pointcuts;

/** 
 * 
@author 作?nbsp;
 * 
@version 创徏旉Q?009-11-6 下午02:18:03 
 * c说?nbsp;
 
*/
public class UnionPointcut implements Pointcut {
    
//声明合ƈ的Pointcut实例
    private Pointcut delegate;
    
    
public Pointcut getDelegate() {
        
return delegate;
    }

    
public void setDelegate(Pointcut delegate) {
        
this.delegate = delegate;
    }
    
//委托lPointcut的方?/span>
    public ClassFilter getClassFilter() {
        
return getDelegate().getClassFilter();
    }

    
public MethodMatcher getMethodMatcher() {
        
return getDelegate().getMethodMatcher();
    }
    
//创徏l合切入?/span>
    public void setPointcuts(List pointcuts){
        
if(pointcuts == null || pointcuts.size()==0){
            System.out.println(
"没有要组合的切入?/span>");
        }
        delegate 
= (Pointcut)pointcuts.get(0);
        
for(int i=1;i<pointcuts.size();i++){
            Pointcut pointcut 
= (Pointcut)pointcuts.get(i);
            delegate 
= Pointcuts.union(delegate,pointcut);
        }
    }

}
映射文g如下Q?br />
<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<bean id="frequentCustomerAdvice" class="com.wyq.spring.common.aopinstance.namemachmethodpointcut.PrequentCustomerAdvice"></bean>
    
    
<bean id="queryInterceptor" class="com.wyq.spring.common.aopinstance.namemachmethodpointcut.QueryInterceptor"></bean>
    
    
<bean id="unionpointcut" class="com.wyq.spring.common.aopinstance.composablepointcut.UnionPointcut">
        
<property name="delegate">
            
<ref bean="frequentCustomerPointcutAdvisor"/>
        
</property>
        
<property name="pointcuts">
            
<list>
                
<ref bean="queryPointCutAdvisor"/>
            
</list>
        
</property>
    
</bean>
    
<bean id="frequentCustomerPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        
<property name="mappedName">
            
<value>order*</value>
        
</property>
        
<property name="advice">
            
<ref bean="frequentCustomerAdvice"/>
        
</property>
    
</bean>
    
    
<bean id="queryPointCutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        
<property name="pattern">
            
<value>.*get.+By.+</value>
        
</property>
        
<property name="advice">
            
<ref bean="queryInterceptor"/>
        
</property>
    
</bean>
</beans>



]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301412.html王永?/dc:creator>王永?/author>Fri, 06 Nov 2009 04:29:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301412.htmlhttp://m.tkk7.com/wyxdeniro/comments/301412.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/06/301412.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/301412.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/301412.html
是,实现q个接口的类必须臛_有一个如下Ş式的Ҏ(gu)Q?br />     void afterThrowing(Throwable throwable);
    void afterThrowing(Method method,Object[] args,Object target,Throwable throwable);
W一个方法只接受一个参敎ͼ(x)需要抛出的异常。第二个Ҏ(gu)接受异常、被调用的方法、参C?qing)目标对象。除非需要这些外加参敎ͼ你只要实现单参数Ҏ(gu)可以了。你的ThrowsAdvice要处理的异常取决于你的方法定义的异常cd?br />     你也可以在一个类中实现多个afterThrowingҎ(gu)。代码如下:(x)

package com.wyq.spring.base.aopinstance;

import org.springframework.aop.ThrowsAdvice;

/** 
 * 
@author 作?nbsp;
 * 
@version 创徏旉Q?009-11-5 下午05:39:17 
 * c说?nbsp;
 
*/
public class KwikEMartExceptionAdvice implements ThrowsAdvice {
    
/*
     * Ҏ(gu)抛出异常的类型恰当方法将被调用。注意,除了捕获和处理异总外,q些Ҏ(gu)都ؓ(f)应用d了新的行为?br />      * q是因ؓ(f)你无法做到这一炏V代理对象捕获异常ƈ且调用合适的ThrowsAdviceҎ(gu)Q如果有的话。ThrowsAdvice
     * 被执行后Q原来的异常l箋被抛出,q且向其他异怸栯传播出去?br />      
*/
    
public void afterThrowing(NoMoreSquisheesException e){
        orderMoreSquishees();
    }
    
public void afterThrowing(CustomerIsBrokeException e){
        showCustomerAtmMachine();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<!-- 创徏代理目标对象 -->
    
<bean id="kwikEMartTarget" class="com.springinaction.chapter03.store.ApuKwikEMart"></bean>
    
<!-- 创徏通知 -->
    
<bean id="welcomeAdvice" class="com.springinaction.chapter03.store.WelcomeAdvice"></bean>
    
<!-- 创徏代理对象 -->
    
<bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean">
        
<!-- 代理cd现的接口 -->
        
<property name="proxyInterfaces">
            
<value>com.springinaction.chaper03.store.kwikEMart</value>
        
</property>
        
<!-- 要织入的通知 -->
        
<property name="interceptorNames">
            
<list>
                
<value>welcomeAdvice</value>
            
</list>
        
</property>
        
<!-- 要代理的目标对象 -->
        
<property name="target">
            
<ref bean="kwikEMartTarget"/>
        
</property>
    
</bean>
</beans>


    引入通知Q引入通知与前面的通知cd有点不同。其他类型的通知是在目标对象的方法被调用的周围织入。引入通知l目标对象添加新的方法?br />     切入点决定了一个特定类的特定方法是否满一条特定规则。如果一个方法确实符合,通知应用到该方法上。Spring的切入点可以让我们以一U灵zȝ方式定义在什么地方将通知l入到我们的cM?br />     SpringҎ(gu)需要织入通知的类和方法来定义切入炏VSpring的切入点框架的核心接口自然史pointcut.
    public interface Pointcut{
        ClassFilter getClassFilter();//q个接口军_了一个类是否复合通知的要?br />     MethodMatcher getMethodMatcher();//Ҏ(gu)qo(h)
    }
大多数切面是由定义切面行为的通知和定义切面在什么地Ҏ(gu)行的切入点组合而成的。Spring认识到这一点,提供了AdvisorQ?br />
它把通知和切入点l合C个对象中?br />    public interface PointcutAdvisor{
       Pointcut getPointcut();
    Advice getAdvice();
   }
大多数Spring自带的切入点都有一个对应的PointcutAdvisor.q样方便你在一个地方定义切入点和通知?br />
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<!-- 创徏代理目标对象 -->
    
<bean id="maidServiceTarget" class="com.springinaction.chapter03.cleaning.MaidServiceImpl"></bean>
    
<!-- 创徏通知 -->
    
<bean id="frequentCustomerAdvice" class="com.springinaction.chapter03.cleaning.FrequentCustomerAdvicer"></bean>
    
<!-- 定义切入?nbsp;
         使用Namedmethodmatcher可以很清楚的指明哪些Ҏ(gu)需要用通知。然而,对于大型应用pȝQ把每个需要通知的方法都列出?br />          ?x)配置文g昑־非常冗长。用通配W可以帮助我们解册个问题?br />          Spring的RegexpMethodPointcut让你利用正则表达式的力量来定义切入点。这样你可以使用Perl样式的正则表辑ּ来定义模式,
         以得C惌的方法?br />          .匚wM单个字符
         +匚w前一个字W一ơ或多次
         *匚w前一个字W?ơ或多次
         \匚wM正则表达式符?br />     
-->
    
<bean id="frequentCustomerPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        
<property name="mappedName">
            
<value>order*</value>
        
</property>
        
<property name="advice">
            
<ref bean="frequentCustomerAdvice"/>
        
</property>
    
</bean>
    
<!-- 如果你想匚w所有setXxxҎ(gu)Q我们需要?*set*.模板(W一个通配W匹配Q何类? -->
    
<bean id="queryPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        
<property name="pattern">
            
<value>.*get.+By.+</value>
        
</property>
        
<property name="advice">
            
<ref bean="frequentCustomerAdvice"/>
        
</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>frequentCustomerAdvisor</value>
            
</list>
        
</property>
        
<property name="target">
            
<ref bean="maidServiceTarget"/>
        
</property>
    
</bean>
</beans>




]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/05/301317.html王永?/dc:creator>王永?/author>Thu, 05 Nov 2009 09:31:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/05/301317.htmlhttp://m.tkk7.com/wyxdeniro/comments/301317.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/05/301317.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/301317.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/301317.html
托模式。但׃基础cdpȝ中到处用,使用l承?x)引赯ql承关系。委托模式比较笨拙,依然需要重复调用委托对?br />
。用AOPQ你也是在一个地方定义通用功能Q只是你可以声明式定义何时何地应用这些功能,而不一q欧冠在需要新功能的地

方修改代码。交叉业务现在可以被模块化到特定对象切面中。这样做?个好处,W一Q现在每个业务逻辑攑֜一个地方,而不

是分散到代码的各个角落。第二,我们的服务模块现在更加清晎ͼ因ؓ(f)他们只包含他们的核心功能Q辅助功能{Ud切面中?br />
    切面(Aspect):切面是你要实现的交叉功能。切面最常用的例子是日志记录。日志记录在pȝ中到处需要用到?br />     q接?Joinpoint):q接Ҏ(gu)应用E序执行q程中插入切面的地点。这个地点可以是Ҏ(gu)调用Q异常抛出,或者是要修?br />
字段。切面代码在q些地方插入C的应用流E中Q添加新的行为?br />     通知(Advice):通知切面的实际实现。它通知应用pȝ新的行ؓ(f)?br />     切入?PointCut):切入点定义了通知应该应用在哪些连接点。通知可以应用到AOP框架支持的Q何连接点。你q不希望?br />
所有切面应用到所有可能的q接点上。切入点让你指定通知应用C么地斏V?br />     引入(Introduction):引入允许你ؓ(f)已存在类d新方法和属性?br />     目标对象(Target):目标对象是被通知对象。它既可以是你编写的cM可以是你要添加定制行为的W三方类?br />     代理(Proxy)Q代理是通知应用到目标对象后创徏的对象。对于客户对象来_(d)目标对象和代理对象是一L(fng)?br />     l入(Weaving):l入是将切面应用到目标对象从而创Z个新的代理对象的q程?br />     切入点定义了哪些q接点要被通知?br />
    Spring的AOP实现Q?br />     在Spring中所有的通知都以Javacȝ形式~写。代理Bean只有在第一ơ被应用pȝ需要的时候才被创建。如果你使用的是ApplicationContext,代理对象在BeanFactory载入所有Bean的时候被创徏。因为Spring在运行期创徏代理Q所以用Spring AOP不需要特D编译期?br />     Spring?U代理创建方式。如果目标对象实C一个接口暴露的Ҏ(gu)QSpring用JDK的Java.lang.reflect.ProxycdZ理。这个类让Spring动态生一个新的类Q它实现了所需的接口,l入了通知Qƈ且代理对目标对象的所有请求?br />     如果目标对象没有实现M接口QSpring使用CGLIB库生成目标对象的子类。在创徏q个子类的时候,Spring通知l入Qƈ且对目标对象的调用委托给q个子类?br />
    通知包含了切面的逻辑。所以当你创Z个通知对象的时候,你是在编写实C叉功能的代码。而且Q记住Spring的连接点模型是徏立在Ҏ(gu)拦截上。这意味着你编写的Spring通知?x)在?gu)调用周围的各个地方织入系l中。通知的类型有QAround,Before,After,Throws

前置通知Q需要扩展MethodBeforeAdvice接口
public interface MethodBeforeAdvice{
    void before(Method method,Object[] args,Object target)throws Throwable;
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<!-- 创徏代理目标对象 -->
    
<bean id="kwikEMartTarget" class="com.springinaction.chapter03.store.ApuKwikEMart"></bean>
    
<!-- 创徏通知 -->
    
<bean id="welcomeAdvice" class="com.springinaction.chapter03.store.WelcomeAdvice"></bean>
    
<!-- 创徏代理对象 -->
    
<bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean">
        
<!-- 代理cd现的接口 -->
        
<property name="proxyInterfaces">
            
<value>com.springinaction.chaper03.store.kwikEMart</value>
        
</property>
        
<!-- 要织入的通知 -->
        
<property name="interceptorNames">
            
<list>
                
<value>welcomeAdvice</value>
            
</list>
        
</property>
        
<!-- 要代理的目标对象 -->
        
<property name="target">
            
<ref bean="kwikEMartTarget"/>
        
</property>
    
</bean>
</beans>

ProxyFactoryBeancL一个在BeanFactory中显C的创徏代理对象的中心类。像我们展示的那P你可以给它一个要实现的接口,一个要代理的目标对象,一个要l入的通知Qƈ且它?yu)创Z个崭新的代理对象。通常配置ProxyFactoryBean,让它实现和目标对象一L(fng)接口?br />
后置通知Q需要实现AfterReturningAdvice
public interface AfterReturningAdvice{
    void afterReturning(Object returnValue,Method method,Object[] args,Object target)throws Throwable;
}

环绕通知Q需要实现MethodInterceptor,同时实现前置和后|通知
public interface MethodInterceptor extends Interceptor{
    Object invoke(MethodInvocation invocation)throws Throwable;
}
MethodInterceptor接口和前面介l的2U通知不同点:(x)
1、MethodInterceptor能够控制目标Ҏ(gu)是否真的被调用。通过调用MethodInvocation.proceed()Ҏ(gu)来调用目标方法。这一点不同于前两个,目标Ҏ(gu)L被调用的?br /> 2、MethodInterceptor让你可以控制q回的对象。就是说你可以返回一个与proceed()Ҏ(gu)q回对象完全不同的对象?br />
package com.wyq.spring.base.aopinstance;

import java.util.HashSet;
import java.util.Set;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jboss.remoting.samples.transporter.basic.Customer;


/** 
 * 
@author 作?nbsp;
 * 
@version 创徏旉Q?009-11-5 下午05:19:19 
 * c说?nbsp;
 
*/
public class OnePerCustomerInterceptor implements MethodInterceptor {
    
//定义包含用户的集?/span>
    private Set customers = new HashSet();
    
/*
     * 当你在方法调用的前后都需要交叉切面逻辑Ӟ应该使用MethodInterceptor。由于你必须要记得显C?br />      * invocation.proceed()Ҏ(gu)Q所以,在满求的情况下,最好还是用MethodBeforeAdvice?br />      * AfterReturningAdvice.
     
*/
    
    
public Object invoke(MethodInvocation invocation) throws Throwable {
         Customer customer 
= (Customer)invocation.getArguments()[0];
         
if(customers.contains(customer)){
             System.out.println(
"抛出异常");
         }
         
//调用目标Ҏ(gu)
         Object squishee = invocation.proceed();
         
//d用户
         customers.add(customer);
         
//q回目标Ҏ(gu)l果
        return squishee;
    }
}



   


]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/11/03/300983.html王永?/dc:creator>王永?/author>Tue, 03 Nov 2009 12:52:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/11/03/300983.htmlhttp://m.tkk7.com/wyxdeniro/comments/300983.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/11/03/300983.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/300983.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/300983.html 有时Q你不希望硬~码昄l用户信息。也许是因ؓ(f)q个信息l常发生改变Q或者是你的应用pȝ提供国际化功能,你要用用L(fng)本地语言昄文本?br /> javaҎ(gu)本国际化的支持你能够定义一个或多个属性文件保存应用系l中需要显C的文本。Spring的ApplicationContext通过MessageSource接口为容器提供参数化信息支持QSpring提供了一个现成的MessageSource实现。ResourceBundleMessageSource只是调用java自己的java.util.ResourceBundle来解析信息?br /> 例如Q?br />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        
<property name="basename">
            
<value>trainingtext</value>
        
</property>
    
</bean>

q个Bean的名字必LmessageSource,因ؓ(f)ApplicationContext在装配应用系lBean的时候查找这个名字的Bean,你不需要将messageSource注入到应用系l中的Bean中,而是使用ApplicationContext自己的getMessage()Ҏ(gu)?br /> Locale locale = ...;
W一个参数表C文本文件中的ID
W二个参数表CZ递到资源文g中的数组Q显C最l文?br /> W三个参数表C采用哪U方式显C?br /> String text  = context.getMessage("computer",new Object[0],locale);

监听事g与发布事Ӟ(x)

如果你想对一个类的方法进行监听,首先要定义事Ӟ然后在这个方法中通过ApplicationContext发布它,最后在ApplicationContext.xml中定义这个监听器。这P每当Ҏ(gu)执行的时候,监听器就?x)监听到对应的事件的触发?br />
事g分ؓ(f)ApplicationContext发布的事件和自定义的事g。这些事仉是抽象类org.springframework.context.ApplicationEvent的子cR?br /> 在应用系l生命周期中QApplicationContext?x)发布很多事Ӟ告诉感兴的监听器发生了什么事情。。系l事件有如下几个Q?br /> 1、ContextClosedEvent:在应用上下文关闭的时候发布的事gQ?br /> 2、contextRefreshedEvent:在应用上下文初始化或h的时候发布的事gQ?br /> 3、RequestHandledEvent:在web应用上下文中Q当一个请求被处理后发布的事g?br /> 首先要编写ؓ(f)哪个cȝ哪个Ҏ(gu)d事gQ?br />
public class Animal implements ApplicationContextAware {
 
     
private ApplicationContext ac;
 
     
private String name;
 
     
private int age;
 
     
public String speak(){
 
          ac.publishEvent(
new AnimalSpeakEvent(this,this.name));
         
return " 我的名字?"+this.name+",我的q龄?"+this.age;
    }
 
 
    
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
     
this.ac = arg0;
    }
 
 
//Getet和Seter省略
 
 }

自定义事件入下:(x)
import org.springframework.context.ApplicationEvent;
 
 
public class AnimalSpeakEvent extends ApplicationEvent {
 
     
private static final long serialVersionUID = 1L;
 
     
private String animalName;
 
     
public AnimalSpeakEvent(Object source) {
         
super(source);
     }
 
     
public AnimalSpeakEvent(Object source,String animalName) {
         
super(source);
         
this.animalName = animalName;
     }
 
     
public String getAnimalName() {
         
return animalName;
     }
 
 }

然后是实现监听器Q监听器必须实现org.springframework.context.ApplicationListener接口。这个接口要求你的Bean实现onApplicationEvent()Ҏ(gu)Q?br />
public class RefreshListener implements ApplicationListener{
    
public void onApplicationEvent(ApplicationEvent event){
    }
}

import org.springframework.context.ApplicationEvent;
 
import org.springframework.context.ApplicationListener;
 
 
public class AnimalEventListener implements ApplicationListener {
 
     
public void onApplicationEvent(ApplicationEvent event) {
         
if (event instanceof AnimalSpeakEvent) {
             AnimalSpeakEvent a 
= (AnimalSpeakEvent) event;
                 System.out.println(
"事g监听?/span>" + this.getClass().getSimpleName()+":有一个动物在讲话Q它的名字是:"+ a.getAnimalName());
         }
     }
 }

最后就是在映射文g中定义这个监听器Q?br />
<?xml version="1.0" encoding="UTF-8"?>
 
<beans  …………>
 
     
<bean id="Listener" class="ioc.test.AnimalEventListener" />
 
     
<bean id="Animal" class="ioc.test.Animal">
       
<property name="name" value="老虎" />
       
<property name="age" value="5" />
     
</bean>
 
 
</beans>
最后是试c:(x)
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 
public class TestMain {
 
     
public static void main(String[] args) {
 
         AbstractApplicationContext ac 
= new ClassPathXmlApplicationContext(
                 
"applicationContext.xml");
 
         
//从容器获取动物实?/span>
         Animal animal = (Animal)ac.getBean("Animal");
 
         
//让动物讲?/span>
         System.out.println(animal.speak());                
     }
 }


感知其他Bean:
    在极大程度上Q运行在Spring容器中的Bean像生活在The Matrix里的人类。对于这些Bean来说Q他们不知道自己的注册名Q甚至不知道自己q行在容器中。通常q是好事Q因为如果一个Bean知道容器的存在的话,他就和Spring耦合在一起了Q在容器以外无法存在?br />     但有时候Bean需要知道更多信息。有时他们需要知道他们是谁,他们在哪里运行。有时他们需要服用那颗红色药丸?br />     在Spring Bean环境中,U色药丸是BeanNameAware、BeanFactoryAware和ApplicationContextAware接口。通过实现q?个接口,Bean分别可以知道自己的名字,他们所处的BeanFactory以及(qing)他们所处的ApplicationContext.
    注意Q通过实现q些接口Q一个Bean和Spring耦合在一赗?br />
    感知pȝ容器对于Bean来说是福是祸。一斚wQ应用上下文的获得给Bean提供了很多权利。另一斚wQ知道容器会(x)把Bean和Spring耦合hQ这是要量避免的事情?nbsp;   



]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/10/31/300494.html王永?/dc:creator>王永?/author>Sat, 31 Oct 2009 09:54:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/31/300494.htmlhttp://m.tkk7.com/wyxdeniro/comments/300494.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/31/300494.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/300494.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/300494.html 有时你会(x)发现配|文件分成几个分散的配置文g是很有益的?br /> Data Source配置到Bean装配文g中不是很适合。数据库l节是一个发布信息。而Bean装配文g的目的是定义如何装配pȝ的各个模块。如果用ApplicationContext当作Spring容器Q那么,在Spring中分d性配|是很简单的。用Spring的PropertyPlaceholderConfigurer告诉Spring从外部属性文件装载一些配|信息?br />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        
<property name="url">
            
<value>jdbc:hsqldb:Training</value>
        
</property>
        
<property name="driverClassName">
            
<value>org.hsqldb.jdbcDriver</value>
        
</property>
        
<property name="username">
            
<value>appUser</value>
        
</property>
        
<property name="password">
            
<value>password</value>
        
</property>
    
</bean>
location属性告诉Spring从哪里找到属性文件。location属性允怽使用单个配置文g。如果你惛_配置信息分散到多个配|文件中Q请? 用PropertyPlaceholderConfigurer的locations属性设|文件列表,使用q种方式Q可以用占位符变量代替Bean? 配文件中的硬~码配置了?br />
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        
<property name="location">
            
<value>jdbc.properties</value>
        
</property>
        
<property name="locations">
            
<list>
                
<value>jdbc.properties</value>
                
<value>security.properties</value>
                
<value>application.properties</value>
            
</list>
        
</property>
    
</bean>
    
<bean id="dataSources" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        
<property name="url">
            
<value>${database.url}</value>
        
</property>
        
<property name="driverClassName">
            
<value>${database.driver}</value>
        
</property>
        
<property name="username">
            
<value>${database.user}</value>
        
</property>
        
<property name="password">
            
<value>${database.password}</value>
        
</property>
    
</bean>

定制属性编辑器Q?br /> java.beans.PropertyEditor接口提供了将字符串值映成非Stringcd的方法。有一个好用的q个接口的实?

java.beans.PropertyEditorSupport,它有2个方法我们会(x)感兴:(x)
1、getAsText():Ҏ(gu)q回一个表C属性值的字符丌Ӏ?br /> 2、setAsText(String value):传递进来的字符串赋lBean的属性?br />
Spring带了几种建立在propertyEditorSupport之上的定制编辑器Q包?br />
org.springframework.beans.propertyeditors.URLEditor,它是一个用于将字符串与java.net.URL怺转换的定制编辑器?br /> Spring提供的其他定制编辑器包括Q?br /> 1、ClassEditor-使用包含全称cd的字W串讄java.lang.Class属性?br /> 2、CustormDateEditor-使用某种java.text.DateFormat对象一个字W串讄ljava.util.Date属性?br /> 3、FileEditor-使用包含文g路径的字W串讄java.io.File属性?br /> 4、LocalEditor-使用包含地域信息的字W串讄java.util.Local属性?br /> 5、StringArrayPropertyEditor-一个包含逗号的String转换成String数组属性?br /> 6、StringTrimmerEditor-自动修正字符串属性,可以选择空字符串{变ؓ(f)null.
<bean id="costomEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        
<property name="customEditors">
            
<map>
                
<entry key="com.wyq.spring.PhoneNumber">
                    
<bean id="phoneEditor" class="com.wyq.spring.PhoneEditor"></bean>
                
</entry>
            
</map>
        
</property>
    
</bean>
其中的map中的key表示要添加自定义属性的c,value表示自定义属性实现的cR?br />
package com.wyq.spring;

import java.beans.PropertyEditorSupport;

public class PhoneEditor extends PropertyEditorSupport {
    
    
public void setAsText(String textValue) throws IllegalArgumentException {
        String stripped 
= stripNonNumberic(textValue);
        
        String areaCode 
= stripped.substring(0,3);
        String prefix 
= stripped.substring(3,6);
        String number 
= stripped.substring(6);
        PhoneNumber phone 
= new PhoneNumber(areaCode,prefix,number);
        setValue(phone);
    }
    
private String stripNonNumberic(String original){
        StringBuffer allNumberic 
= new StringBuffer();
        
for(int i=0;i<original.length();i++){
            
char c = original.charAt(i);
            
if(Character.isDigit(c)){
                allNumberic.append(c);
            }
        }
        
return allNumberic.toString();
    }
}




]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/10/29/300182.html王永?/dc:creator>王永?/author>Thu, 29 Oct 2009 06:59:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/29/300182.htmlhttp://m.tkk7.com/wyxdeniro/comments/300182.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/29/300182.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/300182.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/300182.html Set注入法的~点是,它无法清晰的表示出哪些属性是必须的,哪些是可选的。而构造函数注入法的优势是通过构造函数来强制依赖关系?br /> 使用Set注入Ӟ我们通过<property>元素来注入属性的倹{构造函数注入也一P只不q是通过<bean>元素下的<constructor-arg>元素来指定实例化q个bean的时候需要传递的参数。constructor-arg没有name属性?br />
解决构造函数参数的不确定性:(x)
?U方法可以用来处理构造函数的不确定性:(x)通过序号和类型?lt;constructor-arg>元素有一个可选的index属性,可以用它来指定构造函数的序?br /> <bean id="foo" class="com.springinaction.Foo">
    <constructor-arg index="1">
        <value>http://www.manning.com</value>
    </constructor>
    <constructor-arg index="0">
        <value>http://www.springinaction.com</value>
    </constructor>
</bean>
另一U方法是使用type属性。可以通过type属性确定参数的cd
<bean id="foo" class="com.springinaction.Foo">
    <constructor-arg type="java.lang.String">
        <value>http://www.manning.com</value>
    </constructor>
    <constructor-arg type="java.net.URL">
        <value>http://www.springinaction.com</value>
    </constructor>
</bean>

使用构造函数注入的理由Q?br /> 1、构造函数注入强制用依赖契U。就是如果没有提供所有需要的依赖Q一个Bean无法被实例化?br /> 2、由于Bean的依赖都通过它的构造函数设|了Q所以没有必要再写多余的SetҎ(gu)?br /> 3、因为只能通过构造函数设|类的属性,q样你有效的保证了属性的不可变性?br /> Set注入的依据:(x)
1、如果Bean有很多依赖,那么构造函数的参数列表?x)很ѝ?br /> 2、构造函数只能通过参数的个数和cd来区分?br /> 3、如果构造函数的参数中有2个以上是相同cd的,那么很难定每个参数的用途?br /> 4、构造函数注入不利于自n的ѝ?br />
自动装配Q?br /> 你可以让Spring自动装配Q只要设|需要自动装配的<bean>中的autowire属性?br /> <bean id="foo" class="com.springinaction.Foo" autowire="autowire type"/>
byName-视图在容器中L和需要自动装配的属性名相同的Bean.
byType-视图在容器中L一个与需要自动配|的属性类型相同的Bean.
constructor-视图在容器中查找与需要自动装配的Bean的构造参C致的一个或多个Bean.
autodetect-首先试使用congstructor来自动装配,然后使用byType方式?br />
使用Spring的特DBean
~写一个后处理Bean,SpringZ提供?ơ机?x),让你切入到Bean的生命周期中Q检查或者修改它的配|,q叫做后处理Q后处理实在Bean实例化以?qing)装配完成之后发生的。postProcessBeforeInitialization()Ҏ(gu)在Bean初始化之前被调用。postProcessAfterInitialization()Ҏ(gu)在初始化之后马上被调用?br />
package com.wyq.hibernate;


import java.lang.reflect.Field;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class Fuddifier implements BeanPostProcessor {
    
/**
     * postProcessAfterInitialization()Ҏ(gu)循环Bean的所有属性,Ljava.lang.Stringcd的属性。对于每个String属性,把它传递给
     * fuddify()Ҏ(gu)Q这个方法将String变成唠叨用语?br />      
*/
    
public Object postProcessAfterInitialization(Object bean, String name)
            
throws BeansException {
        Field[] fields 
= bean.getClass().getDeclaredFields();
        
try{
            
for(int i=0;i<fields.length;i++){
                
if(fields[i].getType().equals(java.lang.String.class)){
                    fields[i].setAccessible(
true);
                    String original 
= (String)fields[i].get(bean);
                    fields[i].set(bean,fuddify(original));
                }
            }
        }
catch(IllegalAccessException e){
            e.printStackTrace();
        }
        
return bean;
    }
    
/**
     * postProcessBeforeInitialization()Ҏ(gu)没有做Q何有意义的工作,它只是简单的q回没有修改q的Bean.
     
*/
    
public Object postProcessBeforeInitialization(Object bean, String name)
            
throws BeansException {
        
return bean;
    }
    
private String fuddify(String orig){
        
if(orig==null)return orig;
        
return orig.replaceAll("(r|l)""w").replaceAll("(R|L)""W");
    }

}


注册后处理BeanQ如果你的应用系l运行在Bean工厂中,你需要调用工厂的addBeanPostProcessor()Ҏ(gu)来注册BeanPostProcessor.
BeanPostProcessor fuddifier = new Fuddifier();
factory.addBeanPostProcessor(fuddifier);
如果你是使用应用上下文,你只需要像注册其他Bean那样注册后处理Bean.





]]>
Spring学习(fn)W记(?-----Spring in Action http://m.tkk7.com/wyxdeniro/archive/2009/10/29/300137.html王永?/dc:creator>王永?/author>Thu, 29 Oct 2009 02:28:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/29/300137.htmlhttp://m.tkk7.com/wyxdeniro/comments/300137.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/29/300137.html#Feedback2http://m.tkk7.com/wyxdeniro/comments/commentRss/300137.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/300137.html     容器是Spring框架的核心。Spring容器使用IOC理所有组成应用系l的lg。这包括在协作组件之间徏立关联。Spring实际上有2U不同的容器:Bean工厂(org.springframewor.bens.factory.BeanFactory接口定义)是最单的容器Q提供了基础的依赖注入支持。应用上下文(由org.springframework.contextApplicationContext接口定义)建立在Bean工厂基础之上Q提供了pȝ架构服务?br />     (1)、BeanFactoryq个c负责创建和分发B(ti)ean.׃Bean工厂知道应用pȝ中的很多对象Q所以它可以在实例化q些对象的时候,创徏协作对象间的兌关系。这样就把配|的负担从Bean自n以及(qing)Bean的调用者中q出来。在Spring中有几种BeanFactory的实现。其中最怋用的是org.springframework.beans.factory.xml.XmlBeanFactory,它根据XML文g中的定义装蝲Bean.
例如QBeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
q行代码告诉Bean工厂从XML文g中读取Bean的定义信息。但是,现在Bean工厂q没有实例化Bean.Bean是被延迟载入到Bean工厂中的Q就是说Bean工厂?x)立xBean定义信息载入q来Q但是Bean只有在被需要的时候才被实例化?br />       MyBean myBean = (MyBean)factory.getBean("myBean");
当getBean()Ҏ(gu)被调用的时候,工厂׃(x)实例化Beanq且使用依赖注入开始设|Bean的属性?br />     (2)、ApplicationContext的诸多实CQ有3个实现经常用刎ͼ(x)
  ClassPathXmlApplicationContext-从类路径中的XML文g载入上下文定义信息,把上下文定义文g当成c\径资源?br />   FileSystemXmlApplicationContext-从文件系l中的XML文g载入上下文定义信息?br />   XmlWebApplicationContext-从webpȝ中的XML文g载入上下文定义信息?br /> 例如QApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
      ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");
FileSystemXmlApplicationContext只能在指定的路径中寻找foo.xml文gQ而ClassPathXmlApplicationContext可以在整个类路径中寻找foo.xml.
    应用上下文与Bean工厂的另一个重要区别是关于单实例Bean是如何被载入的。Bean工厂延迟载入所有的BeanQ知道getBean()Ҏ(gu)被调用时Bean才被创徏。应用上下文启动后预载入所有的单实例Bean.

    Spring中的Bean~省情况下是单例模式。在容器分配Bean的时候,它Lq回同一个实例。如果想每次得到不同的实例你需要将Bean定义为原型模式。定义ؓ(f)原型模式意味着你是定义一个Bean蓝图Q而不是一个单一的Bean.<bean>的singleton属性告诉这个bean是否是单例的Q如果是true表示是单例的Q如果是false表示是原型的?br />
<bean id="connectionPool" class="com.springinaction.chapter02.MyConnectionPool" init-method="initialize" destroy-method="close"/>

按这样配|,MyConnectionPool被实例化后initialize()Ҏ(gu)马上被调用,lBean初始化池的机?x)。在Bean从容器中删除之前Qclose()Ҏ(gu)释放数据库q接?br />
讑ր注入:(x)它是一U基于标准命名规范的讄Bean属性的技术。JavaBean规范规定使用对应的set和getҎ(gu)来设|和获得Bean的属性倹{?lt;property>元素的子元素<value>用来讄普通类型的属性,子元?lt;ref bean="">用来讄要关联的Bean.

内部Bean:另一U不怋用的装配Bean引用的方法是?lt;property>元素中嵌入一?lt;bean>元素?br />
<bean id="courseService" class="com.springinaction.service.training.CourseServiceImpl">
    
<property name="studentService">
        
<bean class="com.springinaction.service.training.StudentServiceImpl"/>
    
</property>
</bean>

q种装配Bean引用的方式的~点是你无法在其他地斚w用这个StudentServiceImpl实例Q因为它是一个专门的courseServiceBean建立的实例?br />
注入的是对象集:(x)如果你有一个属性是一个列表或是一个Bean引用集合QSpring支持多种cd的集合作为属性?br /> <list><set><map><props>

装配List和数l:(x)装配一个List属性,List里的元素可以是Q何一U元素,包括<value><ref>甚至是其?lt;list>
<property name="barList">
    
<list>
        
<value>bar1</value>
        
<ref bean="bar2"/>
    
</list>
</property>


装配Set:和List一PSet可以包含Mcd的属性?br />
<property name="barSet">
    
<set>
        
<value>bar1</value>
        
<ref bean="bar2"/>
    
</set>
</property>

<set>的用方法和<list>是一L(fng)。唯一不同的地Ҏ(gu)它被装到什么样的属性中?lt;list>是向java.util.List或数l里装配数据Q?lt;set>是向java.util.Set中装配数据?br />
装配Map:
<property name="barMap">
    
<map>
        
<entry key="key1">
            
<value>bar1</value>
        
</entry>
        
<entry key="key2">
            
<value>bar2</value>
        
</entry>
    
</map>
</property>

Map中的<entry>的数值和<list>以及(qing)<set>的一P可以是Q何有效的属性元素。重申一边,包括<value>?lt;ref>?lt;list>甚至是另一?lt;map>。注意,配置<entry>Ӟ属性key的值只能是String.q对于java.util.Map的功能来说有一炚wӞjava.util.Map是允怓Q何类型的对象作ؓ(f)主键的?br />
装配properties:java.util.Properties集合是最后一个能在Spring中装配的集合cR?lt;props>元素来装配它。?lt;prop>元素表示每条属性?br />
<property name="barProps">
    
<props>
        
<prop key="key1">bar1</prop>
        
<prop key="key2">bar2</prop>
    
</props>
</property>


讄null
Z一个属性设为null,你只要?lt;null/>元素p了?br /> 例如Q?br />
<property name="foo"><null/><property>





]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/10/14/298162.html王永?/dc:creator>王永?/author>Wed, 14 Oct 2009 02:48:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/14/298162.htmlhttp://m.tkk7.com/wyxdeniro/comments/298162.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/14/298162.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/298162.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/298162.html     创徏pȝlg之间兌的动作叫做装配。在Spring应用pȝ中,BeanFactory负责装蝲Bean的定义ƈ把它们装配v来?br />     IOC使Y件组件松散连接成为可能,AOP让你能够捕捉pȝ中经怋用的功能Q把它{化ؓ(f)lg?br />     pȝ由很多组件组成,每个lg负责一部分功能Q然而,q些lg也经常带有一些除了核心功能之外的附带功能。系l服务如日志、事务管理和安全l常融入C些其他功能模块中。这些系l服务通常叫做交叉业务Q这是因为它们L分布在系l的很多lg中。通过这些业务分布在多个lg中,l你的代码引入了双重复杂性?br />     ProxyFactoryBean当需要容器提供一个对象时Q它q回一个针对这个对象所有调用的拦截器对象,在调用目标对象方法之前给AOP对象一个先执行的机?x)。AOP对象执行完毕后,控制权{回给q个对象Q由它执行自qd?br />     管Spring的AOP支持可以被用于从pȝ核心|集中分M叉Q务,但是它的主要d是作为Spring对声明式事务支持的基QSpring带有很多为JavaBean提供声明式事务策略的切面。Acegi安全pȝ为JavaBean提供了声明式安全服务?br />


]]>
Spring学习(fn)W记(?-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297983.html王永?/dc:creator>王永?/author>Mon, 12 Oct 2009 13:53:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297983.htmlhttp://m.tkk7.com/wyxdeniro/comments/297983.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297983.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/297983.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/297983.html     核心容器QSpring核心容器为Spring框架提供了基功能。在q个模块中你?x)找到BeanFactory,它是所有基于Spring框架pȝ的核心。BeanFactory采用工厂模式来实现IOC,它将pȝ的配|和依赖关系从代码中独立出来?br />     Application Context模块
    上下文模块是使Spring成ؓ(f)框架的原因。这个模块扩展了BeanFactory.q个模块提供了很多企业服务如电(sh)子邮件服务、JNDI讉K、EJBl承、远E调用以?qing)定时服务,q且支持与模板框架的集成?br />     Spring的AOP模块
    在AOP模块中,Spring寚w向切面提供了丰富的支持。这个模块是为Spring应用pȝ开发切面的基础?br />     JDBC抽象?qing)DAO模块
    Spring的JDBC和DAO模块把这些样板式的代码抽象出来,让你的数据库代码变得单明了?br />     O/R映射集成模块
    Spring不想实现自己的ORM解决Ҏ(gu)Q但是它多流行的ORM框架做了钩子E序Q包括Hibernate、JDO和iBatis映射QSpring的事务管理支持所有这些ORM框架以及(qing)JDBC.
    Spring的web模块
    web上下文模块徏立在应用上下文模块的基础之上Q提供了适合webpȝ的上下文?br />     Spring MVC框架
    Spring为webpȝ提供了全功能的MVC框架?br />     应用Q?br />     使用<property>元素表示讄属性倹{?lt;constructor-arg>元素表示通过构造方法设|参?br />     public class HelloApp{
      public static void main(String[] args)throws Exception{
        BeanFactory factory = new XmlBeanFactory(new FileInputStream("hello.xml"));
        GreetingService greetingService = (GreetingService)factory.getBean("greetingSercice");
        greetingService.sayGreeting();
      }
    }
    q里的BeanFactory是Spring容器。将hello.xml文g载入容器后,main()Ҏ(gu)调用BeanFactory的getBean()Ҏ(gu)来得到问候服务的引用?br />     反向控制Q控制的什么方面被反{了,获得依赖对象的方式反转了?br />     依赖注入QQ何重要的pȝ都需要至?个相互合作的cL完成业务逻辑Q通常Q每个对象都要自p责得到它的合?依赖)对象。你?x)发玎ͼq样?x)导致代码耦合度高而且难以试?br />     使用IOCQ对象的依赖都是在对象创建时p责协调系l中各个对象的外部实体提供的?br />     耦合是一个双头怪物Q一斚wQ紧密耦合的代码难以测试,难以重用Q难以理解,带来典型的摧毁大堤bug.另一斚wQ完全没有耦合的代码什么也做不了。ؓ(f)了做一些有意义的工作,cdM某种方式知道其他cȝ存在。耦合是必ȝQ但需要小心管理?br />     减少耦合的一个通常的做法就是将具体实现隐藏在接口下面,q样具体实现cȝ替换不会(x)影响到引用类?br />


]]>
Spring学习(fn)W记(一)-----Spring in Actionhttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297975.html王永?/dc:creator>王永?/author>Mon, 12 Oct 2009 13:09:00 GMThttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297975.htmlhttp://m.tkk7.com/wyxdeniro/comments/297975.htmlhttp://m.tkk7.com/wyxdeniro/archive/2009/10/12/297975.html#Feedback0http://m.tkk7.com/wyxdeniro/comments/commentRss/297975.htmlhttp://m.tkk7.com/wyxdeniro/services/trackbacks/297975.html      在业务层QSpringZ业应用提供了一个相当全面的解决Ҏ(gu)。这个方案包括数据库持久化支持、声明式事务理、远E服务访问,以及(qing)JMS、Mail、定时等多种企业服务?br />      在WEB层,SpringZ业应用提供了一个MVC框架Q该框架与其他流行的Web框架相比毫不逊色Q而且Spring可以集成各种Web框架和视图技术?br />
    Java可以实现使用分布的模块来建立一个复杂的pȝQ他们ؓ(f)Applet而来Qؓ(f)lg而留?br />     复杂的系l往往需要一些JavaBeans无法直接提供的服务,如事务支持、安全、分布计等Q所以在1998q?月,Sun发不了EJB1.0规范。它把Javalg扩展到服务器端,提供了很多必ȝ企业U服务,但是它不像原来的JavaBean那样单了?br />     现在Javalg开发重新焕发青春,很多新技术包括AOP和Ioc为JavaBean提供了很多EJB才拥有的强大功能Qؓ(f)JavaBeans提供了类gEJB那样的声明式~码模型Q同事没有带来Q何像EJB那样的复杂问题?br />     首先Z么要使用EJB,如果没有使用实体Bean,所以没有用持久化服务Q同样如果没有用远E服务和安全服务。就没有必要使用EJB.EJB之所以复杂是因ؓ(f)EJB是ؓ(f)解决复杂问题而设计的Q如分布式对象和q程事务的问题?br />     作ؓ(f)一个开发者,你始l应该ؓ(f)你的pȝ扑ֈ最好的设计而不是实现。Spring背后的理忉|让你的系l按照你的需求尽量简单。如果你需要的只是使用单Java对象来提供一些支持透明事务的服务的话,使用Springp够了?br />     使用Spring,你的Bean通过接口与它的关联类通信。因Z依赖MҎ(gu)实现Q所以采用Spring的系l是松耦合的,易测试的和易l护的?br />     因ؓ(f)开发Spring应用pȝ使用的都是JavaBeans,所以测试很单。你不需要启动J2EE容器Q因Z试的是一个POJO.
    Spring是ؓ(f)化企业pȝ开发而诞生的。用Spring,你可以用单的JavaBeans来实现那些以前只有EJB才能实现的功能?br />     Spring是一个轻量的Ioc和AOP容器框架
    轻量U:(x)Spring是非侵入式的Q基于Spring开发的pȝ中的对象一般不依赖于Spring的类?br />     反向控制Q用IOCQ对象是被动接收依赖c而不是自׃动去找。可以将IOC理解为JNDI的反?对象不是从容器中查找它的依赖c,而是容器在实例化对象的时候主动将它的依赖cL入给它?br />     面向切面Q通过业务逻辑从系l服务中分离出来Q实C内聚开发。系l对象只做它们该做的-业务逻辑Q它们不负责其他pȝ问题(如日志和事务支持)?br />     容器QSpring是一个容器,是因为它包含q且理pȝ对象的生命周期和配置?br />     框架QSpring实现了用简单的lg配置l合成一个复杂的pȝ?br />


]]>
վ֩ģ壺 ˳߲| ȫaëƬѿ| þþ޾Ʒ| ĻþƷƵ| ޾Ʒ׽þþþþ| ͵Ůϴԡ߹ۿ| ޾Ʒ| avר| ޹ҹӰ| Ļ| Ƶ߹ۿƵ| ˹ƷƵ| Ƶ߹ۿ| ޾Ʒ˳鶹| ̼aƬվ| ŮƵһ| 100000žž18| ۺƷ˿| ëƬaëƬѲ100| Ůɫһ| ձĻ| ߿ʮ˽վ| ޹Ʒר߹ۿ| ĻһӰԺַ| þþƷƷް| ĻƵ| þAV뾫Ʒɫҹ| ɫAAVѲ| ŮƵ| ҹ뾫Ʒѿ| ƷպAV| ձ2019߹ۿ| ɫƷVRһ| ĻӰѿ | Ӱۿ| ޸רպƷ| 2019ĻߵӰ| ޹Ʒѹۿ| ѿƷ鶹| һëƬѲֱۿ| AV벻|