动态代理Proxy

1.类加载器ClassLoader

类加载器就是加载字节码文件(.class)

 

如何获取类加载器:

类名.class.getClassLoader();

                Class clazz = Demo.class;//获得Demo的字节码对象
		ClassLoader classLoader = clazz.getClassLoader();//获得类加载器
		//获得classes(src)下的任何的资源
		String path = classLoader.getResource("com/itheima/classloader/jdbc.properties").getPath();//得到路径
		System.out.println(path);

类加载器的种类:三种

BootStrap:引导类加载器,加载的都是最基础文件

ExtClassLoader:扩张类加载器,加载的都是基础文件

AppClassLoader:应用类加载器,加载的都是第三方jar包和自己的的java文件

三个类加载器的执行顺序由上自下选择(第一个不行第二个上)

 

2.注解(了解)

@Override:告知编译器此方法是覆盖父类的

 

注释:给程序员看到

注解:给jvm记看的(即机器或程序看的)

元注解:注解的注解

 

注解的作用

替代配置文件

优点:方便快捷,@WebServlet("/loginServlet")可以替代web.xml中的servlet配置

缺点:耦合性大,不利于后期维护

 

元注解

@Retention,下面是他的值

SOURCE: 注解在源码级别可见

CLASS:注解在字节码文件级别可见

RUNTIME:注解在整个运行阶段都可见

 

@Target,下面是他的值

代表注解修饰的范围:类上使用,方法上使用,字段上使用

FIELD:字段上可用此注解

METHOD:方法上可以用此注解

TYPE:/接口上可以使用此注解

 

 

3动态代理(spring的aop底层)划重点

不用手动编写一个代理对象,不需要一一编写与目标对象相同的方法,这个过程,在运行时 的内存中动态生成代理对象。

优点:1.可以隐藏委托类的实现,2.解耦:在不修改委托类代码的情况下能够做一些额外的处理。

 

jdk的动态代理实现方法:Proxy.newProxyInstance

接口 proxy = (接口) Proxy.newProxyInstance(委托类的类加载器,委托类的接口,new InvocationHandler(){}匿名内部类);

public static void main(String[] args) {
		final Target target = new Target();/委托类对象	

		//动态创建代理对象
		TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
				target.getClass().getClassLoader(), //委托类的类加载器
				target.getClass().getInterfaces(), //委托类的接口(同一接口)
				new InvocationHandler() {
					@Override
					//被执行几次?------- 看代理对象调用方法几次,代理对象调用接口相应方法 都是调用invoke
					/*
					 * proxy:是代理对象,基本不用(死循环)
					 * method:代表的是目标方法的字节码对象
					 * args:代表是调用目标方法时参数
					 */
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						//反射知识点
						Object invoke = method.invoke(target, args);//目标对象的相应方法
						//retrun返回的值给代理对象
						return invoke;
					}
				}
			);

		//使用动态代理产生的对象(proxy),接口中有下面三个方法,委托类同样也有下面三个方法
		proxy.method1();//调用invoke---Method:目标对象的method1方法  args:null  返回值null
		String method2 = proxy.method2();//调用invoke---Method:目标对象的method2方法  args:null  返回值method2
		int method3 = proxy.method3(100);////调用invoke-----Method:目标对象的method3方法 args:Object[]{100}  返回值100	
	}

要求:必须实现同一个接口,没有接口不能实现jdk的动态代理,还有其他非jdk的动态代理(不需要使用接口)

 

 

 

 

猜你喜欢

转载自blog.csdn.net/langao_q/article/details/81413769