如果在游戏登录的过程中,登录的业务代码是欢迎玩家进入游戏。
//学生类
public class Student {
String name;
int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
}
//业务类
public class LoginImpl implements Login{
@Override
public void welcome(Student student){
System.out.println("欢迎进入瓦罗兰大陆,召唤师 "+student.name);
}
}
这个过程的实现是很简单的。如果这时候老板提出需求,要求年龄验证,小于18岁的未成年人不准登录!这个需求不算是主业务的范围,剥离出来单独使用一个模块进行处理。
//登录验证
public class LoginConvince implements Login {
LoginImpl login;
public LoginConvince(LoginImpl login) {this.login=login;}
public void aop(Student student){
if(student.age < 18){
System.out.println(student.name+",您未满十八岁,无法进入瓦罗兰大陆!");
return;
}else{
System.out.println("验证通过!");
welcome(student);
}
}
@Override
public void welcome(Student student) {
login.welcome(student);
}
}
//测试类
public class Test {
public static void main(String[] args) {
Student student01=new Student("张志明",17);
LoginImpl login=new LoginImpl();
LoginConvince loginConvince=new LoginConvince(login);
loginConvince.aop(student01);
}
}
这个需求就是通过静态代理的方式完成的。
弊端也十分明显,如果有N个委托类,得手动创建N个静态代理类。
动态代理应运而生,通过反射机制和拦截器(实现InvocationHandler),用一个代理类实现动态代理。
public class LoginConvinceProxy implements InvocationHandler {
Object target;
public LoginConvinceProxy(Object object){
this.target=object;
}
//获得委托类的实现对象
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Student student=(Student)args[0];
if(student.age < 18){
System.out.println("您未满十八岁,无法进入瓦罗兰大陆!");
return null;
}else{
System.out.println("验证成功!");
Object result = method.invoke(target, args);
return result;
}
}
}
public class Test {
public static void main(String[] args) {
Student student01=new Student("张志明",22);
Login login=new LoginImpl();
LoginConvinceProxy proxy=new LoginConvinceProxy(login);
Login l=proxy.getProxy();
l.welcome(student01);
}
}