黑马程序员——高新技术(动态代理类)

来源:互联网 发布:手机信号增强器软件 编辑:程序博客网 时间:2024/05/29 03:59

-------android培训、java培训、期待与您交流! ----------

代理的概念与作用
    黑马程序员_高新技术之动态代理类


 class x
{
    void sayHello(){//想知道sayHello方法运行前的时间和运行后的时间
        syso:hello,itcast;
}

class Xproxy//搞一个代理,里面有x的sayHello方法,并在调用方法前后记录下时间。
{
    void sayHello()
{
    starttime
    x.sayHello();
    startend
}

黑马程序员_高新技术之动态代理类


黑马程序员_高新技术之动态代理类


 
面向方面的编程(AOP)

黑马程序员_高新技术之动态代理类


 安全、事务、日志等功能要贯穿到多个模块中,所以,它们就是交叉业务
重要原则:不要把供货商暴露给你的客户。 

动态代理类
1.jvm可以在运行期动态生成出雷的字节码,这种动态生成的类往往被用作代理类,即动态代理类。 
 2.jvm生成的动态类必须实现一个或多个接口,所以,jvm生成的动态类只能用作具有相同接口的目标类的代理。
 3.CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
4.代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置上加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中

分析jvm动态生成的类 打印构造方法与方法参数列表

public class ProxyTest {
public static void main(String[] args){
Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);//一般都用指定接口的类加载器。
System.out.println(clazzProxy1.getName());//com.sun.proxy.$Proxy0
System.out.println("-----------------begin constructorslist--------------");
Constructor[] constructors = clazzProxy1.getConstructors();
for(Constructor constructor : constructors){
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);//单线程用StringBuilder效率高,多线程用StringBuffer
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes();
for(Class clazzParam :clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder);
}
System.out.println("-----------------begin methods--------------");
Method[] methods = clazzProxy1.getMethods();
for(Method method : methods){
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);//单线程用StringBuilder效率高,多线程用StringBuffer
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for(Class clazzParam :clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder);
}
}
}
com.sun.proxy.$Proxy0
-----------------begin constructorslist--------------
com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
-----------------begin methods--------------
hashCode()
equals(java.lang.Object)
toString()
add(java.lang.Object)
contains(java.lang.Object)
isEmpty()
size()
toArray()
toArray([Ljava.lang.Object;)
addAll(java.util.Collection)
iterator()
remove(java.lang.Object)
clear()
containsAll(java.util.Collection)
removeAll(java.util.Collection)
retainAll(java.util.Collection)
isProxyClass(java.lang.Class)
getProxyClass(java.lang.ClassLoader,[Ljava.lang.Class;)
newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler)
getInvocationHandler(java.lang.Object)
getClass()
notify()
notifyAll()
wait(long)
wait(long,int)
wait()

创造动态代理实例对象
System.out.println("------------begin create instance-----------");
//clazzProxy1.newInstance();//调用不带参数的构造方法,但没有不带参数的构造方法。
Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);//InvocationHandler是个接口所以要new它是实现类,我们自己做一个实现类。
class MyInvocationHandler1 implements InvocationHandler{

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHandler1());
System.out.println(proxy1);//toString返回为null,因为对象未创建toString返回空指针异常。
proxy1.clear();
//proxy1.size();//有返回值的方法不能成功调用
Collection proxy2 = (Collection) constructor.newInstance(new InvocationHandler(){

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
});
Collection proxy3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class}, 
new InvocationHandler(){
ArrayList target = new ArrayList();
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// TODO Auto-generated method stub
long beginTime = System.currentTimeMillis();
Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName()+"running time of"+(endTime-beginTime));
return retVal;
}
});
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
proxy3.add("bxd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());//从object继承的方法只有hashCode equals toString派发给InvocationHandler去做。 
} 

黑马程序员_高新技术之动态代理类

黑马程序员_高新技术之动态代理类

黑马程序员_高新技术之动态代理类



1.先写一个系统通告的接口

import java.lang.reflect.Method;

public interface Advice {
 void beforeMethod(Method method);
 void afterMethod(Method method);
}
2.写一个该接口的实现类
import java.lang.reflect.Method;

public class MyAdvice implements Advice {
long beginTime = 0;
public void beforeMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("到传智播客来学习啦!");
beginTime = System.currentTimeMillis();
}

public void afterMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("从传智播客毕业上班啦!");
long endTime = System.currentTimeMillis();
System.out.println(method.getName()+"running time of"+(beginTime-endTime));
}

}

final ArrayList target = new ArrayList();//方法里的内部类访问局部变量要加final
Collection proxy3 = (Collection)getProxy(target,new MyAdvice());
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
proxy3.add("bxd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());//从object继承的方法只有hashCode equals toString派发给InvocationHandler去做。
}

private static Object getProxy(final Object target,final Advice advice) {//方法里的内部类访问局部变量要加final
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// TODO Auto-generated method stub
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
});
return proxy3;
}
} 

实现AOP功能的封装与配置
做一个类似于spring的框架
 黑马程序员_高新技术之动态代理类


 先写一个BeanFactory
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import Proxy.Advice;

public class BeanFactory {
Properties props = new Properties();
public BeanFactory(InputStream ips){//给你一个读取流把配置信息给你
try {
props.load(ips);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object getBean(String name) {
String ClassName = props.getProperty(name);
Object bean = null;
try {
Class
------- android培训、java培训、期待与您交流! ----------详细请查看:http://edu.csdn.net
原创粉丝点击