这里的目的是处理资源的混淆密码。
我们有一个Advisor拦截对setPassword的调用并解密参数。
我们设置了一个看起来像这样的模板:
<bean id="pwAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice"><bean class="our.advice.bean.class"/></property>
<property name="mappedName" value="setPassword"/>
</bean>
<bean id="passwordHandlerTemplate" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true">
<property name="interceptorNames"><list><value>pwAdvisor</value></list></property>
</bean>
我不清楚使用它的确切语法。最明显的方式是:
<bean id="myPasswordProtectedThing" parent="passwordHandlerTemplate">
<property name="target">
<bean class="the.target.class.name">
<property name="password" value="encrypted garbage"/>
</bean>
</property>
</bean>
但是这样做不正常,因为密码属性应用于内部bean,这意味着顾问将不会完成其工作。
那么,这个:
<bean id="myPasswordProtectedThing" parent="passwordHandlerTemplate">
<property name="target"><bean class="the.target.class.name"/></property>
<property name="password" value="encrypted garbage"/>
</bean>
不。 Spring抱怨ProxyFactoryBean没有password属性。而且,当然,事实并非如此。具有password属性的东西是工厂bean 创建的东西。
Bueller?
答案 0 :(得分:1)
我的第一次努力很糟糕,但我很着急。我道歉。现在我想我知道它应该如何运作,因为我相信我已经实现了你想要的东西。
我开始使用Credential类(注意:没有接口):
package aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Credential
{
private static final String DEFAULT_USERNAME = "username";
private static final String DEFAULT_PASSWORD = "password";
private String username;
private String password;
public static void main(String[] args)
{
Credential cred1 = new Credential("foo", "bar");
System.out.println("created using new: " + cred1);
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop-context.xml");
Credential cred2 = (Credential) context.getBean("credential");
System.out.println("created using app context: " + cred2);
String password = ((args.length > 0) ? args[0] : "baz");
cred2.setPassword(password);
System.out.println("initialized using setter: " + cred2);
}
public Credential()
{
this(DEFAULT_USERNAME, DEFAULT_PASSWORD);
}
public Credential(String username, String password)
{
this.setUsername(username);
this.setPassword(password);
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String toString()
{
return new StringBuilder().append("Credential{").append("username='").append(username).append('\'').append(", password='").append(password).append('\'').append('}').toString();
}
}
我创建了一个Decryptor界面:
package aop;
public interface Decryptor
{
String decrypt(String encrypted);
}
和DecryptorImpl:
package aop;
public class DecryptorImpl implements Decryptor
{
public static final String DEFAULT_DECRYPTED_VALUE = " - not secret anymore";
public String decrypt(String encrypted)
{
// Any transform will do; this suffices to demonstrate
return encrypted + DEFAULT_DECRYPTED_VALUE;
}
}
我需要DecryptorAdvice来实现Spring的MethodBeforeAdvice:
package aop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class DecryptionAdvice implements MethodBeforeAdvice
{
private Decryptor decryptor;
public DecryptionAdvice(Decryptor decryptor)
{
this.decryptor = decryptor;
}
public void before(Method method, Object[] args, Object target) throws Throwable
{
String encryptedPassword = (String) args[0];
args[0] = this.decryptor.decrypt(encryptedPassword);
}
}
我在aop-context.xml中将它连接在一起。 (如果你告诉我如何显示XML,我会发布它。)注意passwordDecryptionAdvisor:它只匹配setPassword方法。
有趣的部分发生在我运行时。这是我在控制台中看到的内容:
created using new: Credential{username='foo', password='bar'}
created using app context: Credential{username='stackoverflow', password='encrypted-password'}
initialized using setter: Credential{username='stackoverflow', password='baz - not secret anymore'}
这告诉我的是:
我希望这可以帮到你。
答案 1 :(得分:0)
我认为您希望beforeMethod建议使用传递给setPassword方法的加密密码String。您想解密它并让建议的类获得解密版本。
我也没有在代理工厂中看到代理接口设置。 “Spring In Action”说“......创建一个带接口的代理比代理类更受欢迎......”代理类应该是例外,而不是规则。
发布你的建议课。