proxy 模式
Proxy 分二种,一种称之为静态代理,一种称为动态代理。
public class Person {
protected String name;
protected String ID;
public String getName() {
return name;
}
public String getID() {
return ID;
}
}
public class Buyer extends Person {
// 收入证明
private String income;
// 婚否
private boolean married;
public String getIncome() {
return income;
}
public boolean isMarried() {
return married;
}
public Buyer(String name, String ID, String income, boolean married) {
this.name = name;
this.ID = ID;
}
}
public class HourseTransaction implements ITransaction {
public void valid(Person seller) {
System.out.println("...\n卖房信息以及卖房人产权验证完成");
}
public void credit(Person buyer) {
System.out.println("...\n贷款手续完成\n" + buyer.name + " 贷款办理完成");
}
public void transfer(Person buyer, Person seller) {
System.out.println("...\n过户手续完成\n" + seller.getName()
+ " 房产证、土地证、水、电、煤气、有线电视、宽带等已过户给 " + buyer.getName());
}
}
public class HouseBroker implements ITransaction {
private ITransaction procedure;
public HouseBroker(ITransaction procedure) {
this.procedure = procedure;
}
public void valid(Person seller) {
System.out.println("中介代理验证卖房人产权和其他卖房信息");
procedure.valid(seller);
}
public void credit(Person buyer) {
System.out.println("中介帮 " + buyer.getName() + " 办理贷款手续");
procedure.credit(buyer);
}
public void transfer(Person buyer, Person seller) {
System.out.println("中介帮助将 " + seller.getName() + " 房产过户给 " + buyer.getName());
procedure.transfer(buyer, seller);
}
}
public interface ITransaction {
void valid(Person seller);
void credit(Person buyer);
void transfer(Person buyer, Person seller);
}
public class Seller extends Person {
// 房产所有权证书(房产证、土地证)
private String ownership;
public Seller(String name, String ID, String ownership) {
this.name = name;
this.ID = ID;
this.ownership = ownership;
}
public String getOwnership() {
return ownership;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Person buyer = new Buyer("张三", "123", "收入证明", false);
Person seller = new Seller("李四", "456", "房屋产权证明");
ITransaction procedure = new HourseTransaction();
HouseBroker pi = new HouseBroker(procedure);
pi.valid(seller);
DebugLog.printLogSeperator();
pi.credit(buyer);
DebugLog.printLogSeperator();
pi.transfer(buyer, seller);
}
}
张三要买房,李四要卖房,二者都通过房屋中介相关联,中介负责验证用户,帮买房者贷款,过户。
通过中介者模式,卖房者成功的卖了房,买房者也成功的买到了理想的房子。但是如果增加一个
卖车中介,再每个transaction method之前和之后都需要进行某些操作,应该怎么写呢?
public class Buyer extends Person {
// 收入证明
private String income;
// 婚否
private boolean married;
public String getIncome() {
return income;
}
public boolean isMarried() {
return married;
}
public Buyer(String name, String ID, String income, boolean married) {
this.name = name;
this.ID = ID;
}
}
public class CarTransaction implements ITransaction {
public void valid(Person seller) {
System.out.println("\n car seller info varified");
}
public void credit(Person buyer) {
System.out.println("\n car buyer vehicle loan process finished");
}
public void transfer(Person buyer, Person seller) {
System.out.println("\n car transaction finished");
}
}
public class HouseTransaction implements ITransaction {
public void valid(Person seller) {
System.out.println("...\n卖房信息以及卖房人产权验证完成");
}
public void credit(Person buyer) {
System.out.println("...\n贷款手续完成\n" + buyer.name + " 贷款办理完成");
}
public void transfer(Person buyer, Person seller) {
System.out.println("...\n过户手续完成\n" + seller.getName()
+ " 房产证、土地证、水、电、煤气、有线电视、宽带等已过户给 " + buyer.getName());
}
}
public interface ITransaction {
// 验证卖房信息
void valid(Person seller);
// 办贷款
void credit(Person buyer);
// 房产证、土地证、水、电、煤气、有线电视、宽带等过户
void transfer(Person buyer, Person seller);
}
public class Person {
protected String name;
protected String ID;
public String getName() {
return name;
}
public String getID() {
return ID;
}
}
public class Seller extends Person {
// 房产所有权证书(房产证、土地证)
private String ownership;
public Seller(String name, String ID, String ownership) {
this.name = name;
this.ID = ID;
this.ownership = ownership;
}
public String getOwnership() {
return ownership;
}
}
public class TransactionHandler implements InvocationHandler {
private Object target;
public TransactionHandler(Object dpObj) {
this.target = dpObj;
}
public static Object factory(Object obj) {
Class cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new TransactionHandler(obj));
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("开始动态代理");
Object obj = method.invoke(target, args);
System.out.println("结束动态代理");
return obj;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Buyer buyer = new Buyer("王五", "123", "收入证明", false);
Seller seller = new Seller("麻二", "456", "房屋产权证明");
ITransaction houseProcedure = (ITransaction)TransactionHandler.factory(new HouseTransaction());
houseProcedure.valid(seller);
DebugLog.printLogSeperator();
houseProcedure.credit(buyer);
DebugLog.printLogSeperator();
houseProcedure.transfer(buyer, seller);
ITransaction carProcedure = (ITransaction)TransactionHandler.factory(new CarTransaction());
carProcedure.valid(seller);
DebugLog.printLogSeperator();
carProcedure.credit(buyer);
DebugLog.printLogSeperator();
carProcedure.transfer(buyer, seller);
}
}
通过动态代理可以实现针对截面的编程,但是例子中TransactionHandler beforemethod and aftermethod写得不是很好,
可以重构如下:
public class Buyer extends Person {
// 收入证明
private String income;
// 婚否
private boolean married;
public String getIncome() {
return income;
}
public boolean isMarried() {
return married;
}
public Buyer(String name, String ID, String income, boolean married) {
this.name = name;
this.ID = ID;
}
}
public interface IAdvice {
void before(Method method);
void after(Method method);
}
public interface ITransaction {
// 验证卖房信息
void valid(Person seller);
// 办贷款
void credit(Person buyer);
// 房产证、土地证、水、电、煤气、有线电视、宽带等过户
void transfer(Person buyer, Person seller);
}
public class LoggerAdvice implements IAdvice {
@Override
public void before(Method method) {
DebugLog.log("log before");
}
@Override
public void after(Method method) {
DebugLog.log("log after");
}
}
public class LoginAdvice implements IAdvice {
@Override
public void before(Method method) {
DebugLog.log("login before");
}
@Override
public void after(Method method) {
DebugLog.log("login after");
}
}
public class Person {
protected String name;
protected String ID;
public String getName() {
return name;
}
public String getID() {
return ID;
}
}
public class Procedure implements ITransaction {
public void valid(Person seller) {
System.out.println("\n卖房信息以及卖房人产权验证完成");
}
public void credit(Person buyer) {
System.out.println("\n贷款手续完成\n" + buyer.name + " 贷款办理完成");
}
public void transfer(Person buyer, Person seller) {
System.out.println("\n过户手续完成\n" + seller.getName()
+ " 房产证、土地证、水、电、煤气、有线电视、宽带等已过户给 " + buyer.getName());
}
}
public class Seller extends Person {
// 房产所有权证书(房产证、土地证)
private String ownership;
public Seller(String name, String ID, String ownership) {
this.name = name;
this.ID = ID;
this.ownership = ownership;
}
public String getOwnership() {
return ownership;
}
}
public class TransactionHandler implements InvocationHandler {
private Object target;
private Object iAdvice;
public Object bind(Object delegate,Object advice) {
this.target = delegate;
this.iAdvice = advice;
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class clazz = preExecute(method);
Object obj = method.invoke(target, args);
AfterExecute(method, clazz);
return obj;
}
private void AfterExecute(Method method, Class clazz)throws NoSuchMethodException, IllegalAccessException,InvocationTargetException {
Method end = clazz.getDeclaredMethod("after",new Class[] { Method.class });
end.invoke(this.iAdvice, new Object[] { method });
}
private Class preExecute(Method method) throws NoSuchMethodException,IllegalAccessException, InvocationTargetException {
Class clazz = this.iAdvice.getClass();
Method start = clazz.getDeclaredMethod("before", new Class[] { Method.class });
start.invoke(this.iAdvice, new Object[] { method });
return clazz;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Buyer buyer = new Buyer("王五", "123", "收入证明", false);
Seller seller = new Seller("麻二", "456", "房屋产权证明");
ITransaction transactionLog = (ITransaction) new TransactionHandler().bind(new Procedure(), new LoggerAdvice());
transactionLog.valid(seller);
DebugLog.printLogSeperator();
transactionLog.credit(buyer);
DebugLog.printLogSeperator();
transactionLog.transfer(buyer, seller);
ITransaction transactionLogin = (ITransaction) new TransactionHandler().bind(new Procedure(), new LoginAdvice());
transactionLogin.valid(seller);
DebugLog.printLogSeperator();
transactionLogin.credit(buyer);
DebugLog.printLogSeperator();
transactionLogin.transfer(buyer, seller);
}
}
重构后代码是不是清晰一点了,用过spring的应该都知道通过xml配置bean,那这个到底怎么实现的呢?
public interface Advisor {
public void doInAdvisor(Object proxy, Method method, Object[] args);
}
public class AfterMethodAdvisor implements Advisor {
@Override
public void doInAdvisor(Object proxy, Method method, Object[] args) {
DebugLog.log("after Execute");
}
}
public class AOPHandler implements InvocationHandler {
private Object target;
private Advisor beforeAdvisor;
private Advisor afterAdvisor;
public void setBeforeAdvisor(Advisor beforeAdvisor) {
this.beforeAdvisor = beforeAdvisor;
}
public void setAfterAdvisor(Advisor afterAdvisor) {
this.afterAdvisor = afterAdvisor;
}
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),
this.target.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (beforeAdvisor != null) {
beforeAdvisor.doInAdvisor(proxy, method, args);
}
Object obj = method.invoke(target, args);
if (afterAdvisor != null) {
afterAdvisor.doInAdvisor(proxy, method, args);
}
return obj;
}
}
public class BeanFactory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public void init(String xml) {
try {
SAXReader reader = new SAXReader();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream ins = classLoader.getResourceAsStream(xml);
Document doc = reader.read(ins);
Element root = doc.getRootElement();
Element foo;
AOPHandler aopHandler = new AOPHandler();
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
foo = (Element) i.next();
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
Attribute aop = foo.attribute("aop");
Attribute aopType = foo.attribute("aopType");
if (aop != null && aopType != null) {
Class advisorCls = Class.forName(aop.getText());
Advisor advisor = (Advisor) advisorCls.newInstance();
if ("before".equals(aopType.getText())) {
aopHandler.setBeforeAdvisor(advisor);
} else if ("after".equals(aopType.getText())) {
aopHandler.setAfterAdvisor(advisor);
}
}
Class bean = Class.forName(cls.getText());
Object obj = bean.newInstance();
obj = (Object) aopHandler.bind(obj);
beanMap.put(id.getText(), obj);
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}
public class BeforeMethodAdvisor implements Advisor {
@Override
public void doInAdvisor(Object proxy, Method method, Object[] args) {
DebugLog.log("before Execute");
}
}
public class Buyer extends Person {
private String income;
private boolean married;
public String getIncome() {
return income;
}
public boolean isMarried() {
return married;
}
public Buyer(String name, String ID, String income, boolean married) {
this.name = name;
this.ID = ID;
}
}
public class HouseTransaction implements ITransaction {
public void valid(Person seller) {
System.out.println("...\n卖房信息以及卖房人产权验证完成");
}
public void credit(Person buyer) {
System.out.println("...\n贷款手续完成\n" + buyer.name + " 贷款办理完成");
}
public void transfer(Person buyer, Person seller) {
System.out.println("...\n过户手续完成\n" + seller.getName()
+ " 房产证、土地证、水、电、煤气、有线电视、宽带等已过户给 " + buyer.getName());
}
}
public interface ITransaction {
void valid(Person seller);
void credit(Person buyer);
void transfer(Person buyer, Person seller);
}
public class MetaClass {
public String getModifier(int modifier) {
String result = "";
switch (modifier) {
case Modifier.PRIVATE:
result = "private";
case Modifier.PUBLIC:
result = "public";
case Modifier.PROTECTED:
result = "protected";
case Modifier.ABSTRACT:
result = "abstract";
case Modifier.FINAL:
result = "final";
case Modifier.NATIVE:
result = "native";
case Modifier.STATIC:
result = "static";
case Modifier.SYNCHRONIZED:
result = "synchronized";
case Modifier.STRICT:
result = "strict";
case Modifier.TRANSIENT:
result = "transient";
case Modifier.VOLATILE:
result = "volatile";
case Modifier.INTERFACE:
result = "interface";
}
return result;
}
public void printClassDefinition(Class clz) {
String clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModifier = clzModifier + " ";
}
String superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = "extends " + superClz;
}
Class[] interfaces = clz.getInterfaces();
String inters = "";
for (int i = 0; i < interfaces.length; i++) {
if (i == 0) {
inters += "implements ";
}
inters += interfaces[i].getName();
}
System.out.println(clzModifier + clz.getName() + " " + superClz + " "
+ inters);
System.out.println("{");
Field[] fields = clz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
String modifier = getModifier(fields[i].getModifiers());
if (modifier != null && !modifier.equals("")) {
modifier = modifier + " ";
}
String fieldName = fields[i].getName();
String fieldType = fields[i].getType().getName();
System.out.println(" " + modifier + fieldType + " " + fieldName
+ ";");
}
System.out.println();
Method[] methods = clz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String modifier = getModifier(method.getModifiers());
if (modifier != null && !modifier.equals("")) {
modifier = modifier + " ";
}
String methodName = method.getName();
Class returnClz = method.getReturnType();
String retrunType = returnClz.getName();
Class[] clzs = method.getParameterTypes();
String paraList = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
if (j != clzs.length - 1) {
paraList += ", ";
}
}
paraList += ")";
clzs = method.getExceptionTypes();
String exceptions = "";
for (int j = 0; j < clzs.length; j++) {
if (j == 0) {
exceptions += "throws ";
}
exceptions += clzs[j].getName();
if (j != clzs.length - 1) {
exceptions += ", ";
}
}
exceptions += ";";
String methodPrototype = modifier + retrunType + " " + methodName
+ paraList + exceptions;
System.out.println(" " + methodPrototype);
}
System.out.println("}");
}
}
public class Person {
protected String name;
protected String ID;
public String getName() {
return name;
}
public String getID() {
return ID;
}
}
public class Seller extends Person {
// 房产所有权证书(房产证、土地证)
private String ownership;
public Seller(String name, String ID, String ownership) {
this.name = name;
this.ID = ID;
this.ownership = ownership;
}
public String getOwnership() {
return ownership;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="xxx" class="com.telenav.pattern.proxy.four.HouseTransaction"
aop="com.telenav.pattern.proxy.four.AfterMethodAdvisor" aopType="after" />
</beans>
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Buyer buyer = new Buyer("王五", "123", "收入证明", false);
Seller seller = new Seller("麻二", "456", "房屋产权证明");
// BeanFactory factory = new BeanFactory();
// factory.init("com/telenav/pattern/proxy/four/config.xml");
// ITransaction obj = (ITransaction) factory.getBean("xxx");
// obj.valid(seller);
// obj.credit(buyer);
// obj.transfer(buyer, seller);
// AOPHandler aopHandler= new AOPHandler();
// aopHandler.setAfterAdvisor(new AfterMethodAdvisor());
// ITransaction transaction= (ITransaction)aopHandler.bind(new HouseTransaction());
// transaction.valid(seller);
// transaction.credit(buyer);
// transaction.transfer(buyer, seller);
AOPHandler aopHandler= new AOPHandler();
aopHandler.setAfterAdvisor(new AfterMethodAdvisor());
MetaClass metaClass=new MetaClass();
ITransaction iProcedure= (ITransaction)aopHandler.bind(new HouseTransaction());
metaClass.printClassDefinition(iProcedure.getClass());
iProcedure.valid(seller);
iProcedure.credit(buyer);
iProcedure.transfer(buyer, seller);
}
}