<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>quaff</title>
    <description></description>
    <link>http://quaff.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>使用mixin来记录bean属性的改变</title>
        <author>quaff</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://quaff.javaeye.com">quaff</a>&nbsp;
          链接：<a href="http://quaff.javaeye.com/blog/97704" style="color:red;">http://quaff.javaeye.com/blog/97704</a>&nbsp;
          发表时间: 2007年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          先定义一个需要被introduce的interface<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;EditAware&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Object&nbsp;getOldValue(String&nbsp;propertyName);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;isEdited(String&nbsp;propertyName);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
再写这个interface的mixin<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;org.aopalliance.intercept.MethodInvocation;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.apache.commons.beanutils.PropertyUtils;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;org.apache.commons.lang.StringUtils;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.springframework.aop.support.DelegatingIntroductionInterceptor;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;EditAwareMixin&nbsp;</span><span class="keyword">extends</span><span>&nbsp;DelegatingIntroductionInterceptor&nbsp;</span><span class="keyword">implements</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EditAware&nbsp;{&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">transient</span><span>&nbsp;Map&nbsp;map&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;HashMap();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Object&nbsp;getOldValue(String&nbsp;propertyName)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;map.get(propertyName);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;isEdited(String&nbsp;propertyName)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;map.containsKey(propertyName);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Object&nbsp;invoke(MethodInvocation&nbsp;invocation)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Throwable&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(invocation.getMethod().getName().indexOf(</span><span class="string">&quot;set&quot;</span><span>)&nbsp;==&nbsp;</span><span class="number">0</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;_this&nbsp;=&nbsp;invocation.getThis();&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;propertyName&nbsp;=&nbsp;invocation.getMethod().getName().substring(<span class="number">3</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;propertyName&nbsp;=&nbsp;StringUtils.uncapitalize(propertyName);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;oldValue&nbsp;=&nbsp;PropertyUtils.getProperty(_this,&nbsp;propertyName);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;newValue&nbsp;=&nbsp;invocation.getArguments()[<span class="number">0</span><span>];&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(!isEquals(oldValue,&nbsp;newValue))&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(propertyName,&nbsp;oldValue);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.invoke(invocation);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;isEquals(Object&nbsp;oldValue,&nbsp;Object&nbsp;newValue)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(oldValue&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;&amp;&amp;&nbsp;newValue&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(oldValue&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;oldValue.equals(newValue);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;newValue.equals(oldValue);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
最后是怎么使用这个mixin<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">import</span><span>&nbsp;org.springframework.aop.framework.ProxyFactory;&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">import</span><span>&nbsp;org.springframework.beans.BeanUtils;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Main&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;u1&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;User(</span><span class="string">&quot;username1&quot;</span><span>,&nbsp;</span><span class="string">&quot;password1&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;u2&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;User(</span><span class="string">&quot;username2&quot;</span><span>,&nbsp;</span><span class="string">&quot;password2&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProxyFactory&nbsp;pc&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;ProxyFactory();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc.setProxyTargetClass(<span class="keyword">true</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc.setTargetClass(u1.getClass());&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc.addAdvice(<span class="keyword">new</span><span>&nbsp;EditAwareMixin());&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc.setTarget(u1);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u1&nbsp;=&nbsp;(User)&nbsp;pc.getProxy();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeanUtils.copyProperties(u2,&nbsp;u1);&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EditAware&nbsp;ea&nbsp;=&nbsp;(EditAware)&nbsp;u1;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ea.isEdited(<span class="string">&quot;username&quot;</span><span>));&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ea.getOldValue(<span class="string">&quot;username&quot;</span><span>));&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;User&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;username;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;password;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;User()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;User(String&nbsp;username,&nbsp;String&nbsp;password)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.username&nbsp;=&nbsp;username;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.password&nbsp;=&nbsp;password;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;getUsername()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;username;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setUsername(String&nbsp;username)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.username&nbsp;=&nbsp;username;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;getPassword()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;password;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPassword(String&nbsp;password)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.password&nbsp;=&nbsp;password;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://quaff.javaeye.com/blog/97704#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 04 Jul 2007 11:42:30 +0800</pubDate>
        <link>http://quaff.javaeye.com/blog/97704</link>
        <guid>http://quaff.javaeye.com/blog/97704</guid>
      </item>
      <item>
        <title>Spring容器外注入依赖</title>
        <author>quaff</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://quaff.javaeye.com">quaff</a>&nbsp;
          链接：<a href="http://quaff.javaeye.com/blog/32364" style="color:red;">http://quaff.javaeye.com/blog/32364</a>&nbsp;
          发表时间: 2006年11月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">
package test;

import org.springframework.beans.factory.annotation.Configurable;

@Configurable("testBean")
public class TestBean {
	private TestService testService;

	public TestService getTestService() {
		return testService;
	}
	public void setTestService(TestService testService) {
		this.testService = testService;
	}

}
</pre><br /><pre name="code" class="java">
package test;

public class TestService {
	public String sayHello() {
		return "Hello";
	}
}
</pre><br /><br />&lt;?xml version="1.0" encoding="UTF-8"?><br />&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />	xmlns:aop="http://www.springframework.org/schema/aop"<br />	xmlns:tx="http://www.springframework.org/schema/tx"<br />	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><br />	&lt;aop:spring-configured /><br />	&lt;bean id="testService" class="test.TestService"<br />		depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" /><br />	&lt;bean id="testBean" class="test.TestBean" scope="prototype"><br />		&lt;property name="testService" ref="testService" /><br />	&lt;/bean><br />&lt;/beans><br /><br />在META-INF里面加入aop.xml<br />&lt;!DOCTYPE aspectj PUBLIC<br />"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"><br />&lt;aspectj><br />	&lt;aspects><br />		&lt;include<br />			within="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" /><br />	&lt;/aspects><br />	&lt;weaver<br />		&lt;include within="test.TestBean" /><br />	&lt;/weaver><br />&lt;/aspectj><br /><br />用的是aspectj的加载期植入代码,jvm的启动参数加上-javaagent:aspectjweaver.jar<br /><br />现在来测试<br /><br />package test;<br /><br />import org.springframework.context.support.ClassPathXmlApplicationContext;<br /><br />public class Main {<br /><br />	public static void main(String... strings) {<br />		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(<br />				"applicationContext-test.xml");<br />		TestBean bean = new TestBean();<br />		System.out.println(bean.getTestService());<br />	}<br /><br />}
          <br/>
          <span style="color:red;">
            <a href="http://quaff.javaeye.com/blog/32364#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 03 Nov 2006 20:06:47 +0800</pubDate>
        <link>http://quaff.javaeye.com/blog/32364</link>
        <guid>http://quaff.javaeye.com/blog/32364</guid>
      </item>
      <item>
        <title>动态配置Acegi权限</title>
        <author>quaff</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://quaff.javaeye.com">quaff</a>&nbsp;
          链接：<a href="http://quaff.javaeye.com/blog/28734" style="color:red;">http://quaff.javaeye.com/blog/28734</a>&nbsp;
          发表时间: 2006年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          AbstractRefreshableTargetSource在spring2.0里面才有<br /><br /><pre name="code" class="java">
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.acegisecurity.intercept.web.FilterInvocationDefinitionSourceEditor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.target.dynamic.AbstractRefreshableTargetSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;

public class RefreshableFileFilterInvocationDefinition extends
		AbstractRefreshableTargetSource {
	protected Log logger = LogFactory.getLog(getClass());
	public static final String DEFAULT_LOCATION = "classpath:acegi-filterInvocation.conf";
	private String location = DEFAULT_LOCATION;
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	protected Object freshTarget() {
		ResourceEditor editor = new ResourceEditor();
		editor.setAsText(getLocation());
		Resource resource = (Resource) editor.getValue();
		if (resource == null) {
			logger
					.warn("Can't find a Acegi FilterInvocationDefinition config file");
			return null;
		}
		StringBuffer sb = new StringBuffer();
		char[] cbuf = new char[100];
		int read;
		InputStream is = null;
		InputStreamReader isr = null;
		try {
			is = resource.getInputStream();
			isr = new InputStreamReader(is);
			while ((read = (isr.read(cbuf, 0, cbuf.length))) != -1)
				sb.append(cbuf, 0, read);
			logger.info("loaded Acegi FilterInvocationDefinition config file");
		} catch (IOException e) {
			logger.warn(e.getMessage(), e);
		} finally {
			try {
				if (isr != null)
					isr.close();
				if (is != null)
					is.close();
			} catch (IOException e) {
				logger.warn(e.getMessage(), e);
			}
		}
		FilterInvocationDefinitionSourceEditor configEditor = new FilterInvocationDefinitionSourceEditor();
		configEditor.setAsText(sb.toString());
		return configEditor.getValue();
	}

}
</pre><br /><br />acegi的spring配置文件<br /><br />&lt;bean id="filterInvocationInterceptor"<br />		class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"><br />		&lt;property name="authenticationManager"<br />			ref="authenticationManager" /><br />		&lt;property name="accessDecisionManager"<br />			ref="httpRequestAccessDecisionManager" /><br />		&lt;property name="objectDefinitionSource"<br />			ref="objectDefinitionSource" /><br />	&lt;/bean><br /><br />	&lt;bean id="refreshableFileFilterInvocationDefinition"<br />		class="RefreshableFileFilterInvocationDefinition"><br />		&lt;property name="location" value="file:///${webapp.root}/WEB-INF/acegi-filterInvocation.conf"/><br />		&lt;!-- 自动刷新<br />		&lt;property name="refreshCheckDelay" value="60000"/><br />		--><br />	&lt;/bean><br /><br />	&lt;bean id="objectDefinitionSource"<br />		class="org.springframework.aop.framework.ProxyFactoryBean"><br />		&lt;property name="targetSource"<br />			ref="refreshableFileFilterInvocationDefinition" /><br />	&lt;/bean><br /><br /><br />也可以用dwr来手动刷新,并且配置权限,role是在acegi里面配置的<br /><br />&lt;create creator="spring" javascript="FilterInvocationDefinition"<br />			scope="application"><br />			&lt;param name="beanName" value="refreshableFileFilterInvocationDefinition" /><br />			&lt;auth method="refresh" role="ROLE_SUPERVISOR"/><br />			&lt;include method="refresh" /><br />&lt;/create>
          <br/>
          <span style="color:red;">
            <a href="http://quaff.javaeye.com/blog/28734#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 19 Oct 2006 19:20:52 +0800</pubDate>
        <link>http://quaff.javaeye.com/blog/28734</link>
        <guid>http://quaff.javaeye.com/blog/28734</guid>
      </item>
  </channel>
</rss>