首先定要Proxy的目标,在Spring中默认采用JDK中的dynamic proxyQ它只能够实现接口的代理Q如果想对类q行代理的话Q需要采用CGLIB的proxy。显Ӟ选择“编E到接口”是更明智的做法Q下面是要代理的接口:
public interface FooInterface {
public void printFoo();
public void dummyFoo();
}
以及其一个简单的实现Q?br />
public class FooImpl implements FooInterface {
public void printFoo() {
System.out.println("In FooImpl.printFoo");
}
public void dummyFoo() {
System.out.println("In FooImpl.dummyFoo");
}
}
接下来创Z个AdviceQ在Spring中支持Around,Before,After returning和Throws四种AdviceQ这里就以简单的Before Advice举例Q?br />
public class PrintBeforeAdvice implements MethodBeforeAdvice {
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("In PrintBeforeAdvice");
}
}
有了自己的business interface和adviceQ剩下的是如何去装配它们了Q首先利用ProxyFactory以编E方式实玎ͼ如下Q?br />
public class AopTestMain {
public static void main(String[] args) {
FooImpl fooImpl = new FooImpl();
PrintBeforeAdvice myAdvice = new PrintBeforeAdvice();
ProxyFactory factory = new ProxyFactory(fooImpl);
factory.addBeforeAdvice(myAdvice);
FooInterface myInterface = (FooInterface)factory.getProxy();
myInterface.printFoo();
myInterface.dummyFoo();
}
}
现在执行E序Q神奇的l果出CQ?br />
In PrintBeforeAdvice
In FooImpl.printFoo
In PrintBeforeAdvice
In FooImpl.dummyFoo
虽然q样能体会到Spring中AOP的用法,但这决不是值得推荐的方法,既然使用了SpringQ在ApplicationContext中装配所需?的bean才是最佳策略,实现上面的功能只需要写个简单的applicationContext可以了Q如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<description>The aop application context</description>
<bean id="fooTarget" class="FooImpl"/>
<bean id="myAdvice" class="PrintBeforeAdvice"/>
<bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>FooInterface</value>
</property>
<property name="target">
<ref local="fooTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>myAdvice</value>
</list>
</property>
</bean>
</beans>
当然Qmain中的代码也要q行相应的修改:
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
FooInterface foo = (FooInterface)context.getBean("foo");
foo.printFoo();
foo.dummyFoo();
}
现在q行一下,l果和上面的运行结果完全一Pq样是不是更优雅Q当需要更改实现时Q只需要修攚w|文件就可以了,E序中的代码不需M改动?br />
但是Q这时候会发现被proxy的object中的所有方法调用时都将q行advice中的beforeQ这昄不能满l大多数情况下的需要,此时Q只 需借用Advisor可以了Q当然要在Advisor中利用pattern讄好哪些方法需要adviceQ更改applicationContext 如下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>
<description>The springeva application context</description>
<bean id="fooTarget" class="FooImpl"/>
<bean id="printBeforeAdvice" class="PrintBeforeAdvice"/>
<bean id="myAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="printBeforeAdvice"/>
</property>
<property name="pattern">
<value>.*print.*</value>
</property>
</bean>
<bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>FooInterface</value>
</property>
<property name="target">
<ref local="fooTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>myAdvisor</value>
</list>
</property>
</bean>
</beans>
ȝ序不需q行M修改Q运行结果已l变样了Q?/p>
In PrintBeforeAdvice
In FooImpl.printFoo
In FooImpl.dummyFoo
xQ应该已l理解了Spring中AOP的用方法,当然Spring中AOP最重要的应用是Transaction ManagerQD个这斚w的applicationContext例子看看Q?br />
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd">
<beans>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/jdbc.properties</value>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingResources">
<value>smartmenu.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="smartmenuTarget" class="SmartMenuHibernate">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="smartMenu"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="smartmenuTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</beans>
要想d理解Spring的AOPQ最好还是多看看源码Q开源就是好啊!
java代码: |
package infoweb.dao; import java.util.List; import java.util.Iterator; import infoweb.pojo.Info; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Query; import net.sf.hibernate.Session; import org.springframework.orm.hibernate.HibernateCallback; import org.springframework.orm.hibernate.support.HibernateDaoSupport; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p> * @author D|?br />* @version 1.0 */ publicclass InfoDAOImpl extends HibernateDaoSupport implements IInfoDAO { /** * 构造函?br /> */ public InfoDAOImpl(){ super(); } /** * 增加记录 * @param info Info */ publicvoid setInfo(Info info)throwsException{ getHibernateTemplate().save(info); } /** * 通过ID取得记录 * @param id String * @return Info */ public Info getInfoById(String id)throwsException{ Info info = (Info) getHibernateTemplate().load(Info.class, id); return info; } /** * 修改记录 * @param Info info */ publicvoid modifyInfo(Info info)throwsException{ getHibernateTemplate().update(info); } /** * 删除记录 * @param Info info */ publicvoid removeInfo(Info info)throwsException{ getHibernateTemplate().delete(info); } //////////////////////////////////////////////////////// ///// /// /////以下部䆾不带审核功能 /// ///// /// //////////////////////////////////////////////////////// /** * 取记录L * @return int */ publicint getInfosCount()throwsException{ int count = 0; String queryString = "select count(*) from Info"; count = ((Integer) getHibernateTemplate().iterate(queryString).next()). intValue(); return count; } /** * 取所有记录集?br /> * @return Iterator */ publicIterator getAllInfos()throwsException{ Iterator iterator = null; String queryString = " select info from Info as info order by info.id desc"; List list = getHibernateTemplate().find(queryString); iterator = list.iterator(); return iterator; } /** * 取记录集?br /> * @return Iterator * @param int position, int length */ publicIterator getInfos(int position, int length)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info order by info.id desc"; Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 取第一条记?br /> * @throws Exception * @return Station */ public Info getFirstInfo()throwsException{ Iterator iterator = null; Info info = null; String queryString = "select info from Info as info order by info.id desc"; Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); if(iterator.hasNext()){ info = (Info) iterator.next(); } return info; } /** * 取最后一条记?br /> * @throws Exception * @return Station */ public Info getLastInfo()throwsException{ Iterator iterator = null; Info info = null; String queryString = "select info from Info as info order by info.id asc"; Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); if(iterator.hasNext()){ info = (Info) iterator.next(); } return info; } //////////////////////////////////////////////////////// ///// /// ///// 以下部䆾表中要有特定字段才能Õ吩诵袪 牳鋈撕推W禒 /// ///// /// //////////////////////////////////////////////////////// /** * 取符合条件记录L, [表中要有 isperson 字段] * @return int * @param int isPerson */ publicint getInfosCountByIsperson(int isPerson)throwsException{ int count = 0; String queryString = "select count(*) from Info as info where info.isperson =" + isPerson; count = ((Integer) getHibernateTemplate().iterate(queryString).next()). intValue(); return count; } /** * 取所有符合条件记录集? 模糊查询条g.[表中要有 isperson 字段] * @return Iterator * @param int isPerson */ publicIterator getAllInfosByIsperson(int isPerson)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info where info.isperson =" + isPerson + " order by info.id desc"; List list = getHibernateTemplate().find(queryString); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 取符合条件记录集? 模糊查询条g.[表中要有 isperson 字段] * @return Iterator * @param int isPerson,int position, int length */ publicIterator getInfosByIsperson(int isPerson, int position, int length)throws Exception{ Iterator iterator = null; String queryString = " select info from Info as info where info.isperson =" + isPerson + " order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } //////////////////////////////////////////////////////// ///// /// ///// 以下部䆾表中要有特定字段才能Õ吩诵袪 查询部䆾 /// ///// /// /////////////////////////////////////////////////////// /** * 取符合条件记录L, 模糊查询条g.[表中要有 title 字段] * @return int * @param String text */ publicint getInfosCount(String text)throwsException{ int count = 0; count = ((Integer) getHibernateTemplate().iterate( "select count(*) from Info as info where info.title like '%" + text + "%'").next()).intValue(); return count; } /** * 取所有符合条件记录集? 模糊查询条g.[表中要有 title 字段] * @return Iterator * @param String text */ publicIterator getAllInfos(String text)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info where info.title like '%" + text + "%' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 取符合条件记录集? 模糊查询条g.[表中要有 title 字段] * @return Iterator * @param String text,int position, int length */ publicIterator getInfos(String text, int position, int length)throws Exception{ Iterator iterator = null; String queryString = " select info from Info as info where info.title like '%" + text + "%' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } //////////////////////////////////////////////////////// ///// /// ///// 以下部䆾表中要有特定字段才能Õ吩诵袪 犠⒉嵯喙? /// ///// /// //////////////////////////////////////////////////////// /** * 取符合条件记录L.[ 表中要有 registername 字段] * @return int * @param String text */ publicint getInfosCountByRegisterName(String registerName)throwsException{ int count = 0; count = ((Integer) getHibernateTemplate().iterate( "select count(*) from Info as info where info.registername = '" + registerName + "'").next()).intValue(); return count; } /** * 通过注册名取得一条记?如有多条,只取W一?[表中要有 registername字段] * @param registername String * @return Info */ public Info getInfoByRegisterName(String registerName)throwsException{ Iterator iterator = null; Info info = null; String queryString = " select info from Info as info where info.registername='" + registerName + "' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); if(iterator.hasNext()){ info = (Info) iterator.next(); } return info; } /** * 通过注册名取得所有记录集?[表中要有 registername字段] * @param registername String * @return Iterator */ publicIterator getAllInfosByRegisterName(String registerName)throws Exception{ Iterator iterator = null; String queryString = " select info from Info as info where info.registername='" + registerName + "' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 通过注册名取得记录列?[表中要有 registername字段] * @param registername String * @return Iterator */ publicIterator getInfosByRegisterName(String registerName, int position, int length)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info where info.registername='" + registerName + "' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } //////////////////////////////////////////////////////// ///// /// ///// 以下部䆾表中要有特定字段才能Õ吩诵袪 犑餍桶婵? /// ///// /// //////////////////////////////////////////////////////// /** * 取记录L.[ 表中要有 board_id 字段] * @return int * @param String boardId */ publicint getInfosCountByBoard(String boardId)throwsException{ int count = 0; count = ((Integer) getHibernateTemplate().iterate( "select count(*) from Info as info where info.boardId = '" + boardId + "'").next()).intValue(); return count; } /** * 通过版块名取得所有记录集?[表中要有 board_id字段] * @param BoardId String * @return Iterator */ publicIterator getAllInfosByBoard(String boardId)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info where info.boardId='" + boardId + "' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 通过版块名取得记录列?[表中要有 board_id字段] * @param BoardId String * @return Iterator */ publicIterator getInfosByBoard(String boardId, int position, int length)throws Exception{ Iterator iterator = null; String queryString = " select info from Info as info where info.boardId='" + boardId + "' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } /** * 取符合条件记录L.[ 表中要有 board_id 字段,title] 模糊查询title * @return int * @param String boardId ,String text */ publicint getInfosCountByBoard(String boardId, String text)throwsException{ int count = 0; count = ((Integer) getHibernateTemplate().iterate( "select count(*) from Info as info where info.boardId='" + boardId + "' and info.title like '%" + text + "%'").next()).intValue(); return count; } /** * 通过版块名取得记录列?[表中要有 board_id字段] 模糊查询title * @param String boardID,int position, int length * @return Iterator */ publicIterator getInfosByBoard(String boardId, int position, int length, String text)throwsException{ Iterator iterator = null; String queryString = " select info from Info as info where info.boardId='" + boardId + "' and info.title like '%" + text + "%' order by info.id desc"; //创徏查询 Query query = getHibernateTemplate().createQuery(getSession(), queryString); //讄游标的v始点 query.setFirstResult(position); //讄游标的长?/span> query.setMaxResults(length); //记录生成 List list = query.list(); //把查询到的结果放入P代器 iterator = list.iterator(); return iterator; } //////////////////////////////////////////////////////// ///// /// /////以下部䆾带有审核功能 /// ///// /// //////////////////////////////////////////////////////// /** * 取记录L * @return int * @param int isAuditing */ publicint getInfosCount(int isAuditing)throwsException{ |
Spring Framework最得以出名的是与Hibernate的无~链接,基本上用SpringQ就会用Hibernate。可惜的是Spring提供的HibernateTemplate功能昑־不够Q用v来也不是很方ѝ我们编E序Ӟ一般先写BusinessServiceQ由BusinessService调DAO来执行存储,在这斚wSpring没有很好的例子,造成真正想用好它Qƈ不容易?/font> 我们的思\是先写一个BaseDaoQ仿照HibernateTemplateQ将基本功能全部实现Q?/font> public class BaseDao extends HibernateDaoSupport{ private Log log = LogFactory.getLog(getClass());
public Session openSession() {
public Object get(Class entityClass, Serializable id) throws DataAccessException {
public Serializable create(Object entity) throws DataAccessException { ... 其它的DAOQ从BaseDaol承出来Q这样写其他的DAOQ代码就会很?/font> 从BaseDaol承出来EntityDaoQ专门负责一般实体的基本操作Q会更方ѝ?/font> public interface EntityDao { public Object get(Class entityClass, Serializable id) throws DataAccessException; public Object load(Class entityClass, Serializable id) throws DataAccessException;
public Serializable create(Object entity) throws DataAccessException;
/** } ZTransaction的控Ӟ采用AOP的方式: public interface EntityManager { public Object get(Class entityClass, Serializable id); public Object load(Class entityClass, Serializable id);
public Serializable create(Object entity); }
/** private EntityDao entityDao;
public void setEntityDao(EntityDao entityDao) {
public Object get(Class entityClass, Serializable id) {
public Object load(Class entityClass, Serializable id) { } q样我们有了一个通用的Hibernate实体引擎Q可以对MHibernate实体实现基本的增加、修攏V删除、查询等?/font> 其它的BusinessService可以承EntityManagerQ快速实C务逻辑?/font> 具体XML配置如下Q?/font>
<!-- Oracle JNDI DataSource for J2EE environments -->
<!-- Hibernate SessionFactory for Oracle -->
<!-- AOP DAO Intecepter -->
<bean id="entityDaoTarget" class="com.gpower.services.entity.dao.EntityDaoImpl">
<bean id="entityDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
<!-- Transactional proxy for the Application primary business object -->
<bean id="entityManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> |
![]() |