记录学习内容
今天主要学习:动态代理、注解、类加载器
一、动态代理
作用:增强某个方法。
增强一个对象的方法通常有三种:
1、继承,继承父类后重写方法。
优点:简单,易实现,继承类后重写方法即可。
缺点:需要知道增强的方法的父类。
2、装饰者模式,使用装饰者模式,装饰者和被装饰者实现同一个接口后增强该方法。
优点:不需要知道需要增强的对象的父类,只需要知道实现了哪一个接口就可以了。
缺点:如果接口内方法较多,那么需要全部实现方法,工作量较大。
3、动态代理。
动态代理就是使用java自带的proxy创建一个代理类来实现指定方法的增强。
有点:不需要实现接口中的所有方法,只需要重写需要增强的方法即可。
缺点:实现难度大
代码:
package com.topscomm.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
/*
* 细节1、method.invoke()谁调用都会执行
*
*/
public class demo3 {
@Test
public void test() {
final NomalPerson p =new NomalPerson();
p.run();
person Proxyperson = (person)Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(),
new InvocationHandler() {
//参数含义
//proxy 固定格式不用管,method传递进来的方法,也就是需要增强的方法,args方法参数
//关于返回值:如果原来方法中存在返回值则return会覆盖返回值,如果原来方法没有返回值则返回值不会传递回去。
//只会增强接口中的方法,接口未定义的方法不会增强
//如果需要过滤掉不需要增强的方法则只需要使用if语句进行过滤即可
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if("run".equals(method.getName())) {
method.invoke(p, args);//此处会执行原来的方法,args就是参数,如果原来的方法没有参数则不会传递
System.out.println("会飞了");
return null;
}else {
return method.invoke(p, args);
}
}
});
Proxyperson.run1();
}
}
使用装饰者模式实现同样案例:
public class supurPerson implements person{
/*
* 装饰者模式实现类方法增强
* (non-Javadoc)
* @see com.topscomm.com.demo2.person#run()
*/
NomalPerson p = new NomalPerson();
public supurPerson(NomalPerson p) {
this.p=p;
}
public void run() {
// TODO Auto-generated method stub
p.run();
System.out.println("会飞了");
}
}
案例:使用动态代理解决servelet中的get请求提交中文乱码
注解:样式:@加一串字符串
开发只需要记住:1、注解是起到什么作用
2、注解可以加在那里。注解加在哪里是由元注解决定的,可以加在变量,方法,类中。
注解底层实现实际是一个接口,如果接口中有方法则需要在方法中加上value值。其中spring中大量使用了注解。
注解的属性名–接口方法的方法名
注解的属性值–接口方法的返回值
元注解:@Target:该注解可以放在哪些地方
@Retention 指定注解在什么时间有效
类加载器:类加载器是将.class文件加载到内存中形成class对象,这个过程就是类加载。
做这件事情的东西就是类加载器。
类加载气的组成:
引导类加载器(负责加载 rt.jar)
扩展类加载器(负责加载rt.jar以外的类)
应用加载器(加载自己编写的类)
为了保证一个类只能被加载一次,使用了“全面托管机制”
作用原理:
当应用类加载器拿到一个类,先不做处理交给扩展加载器
扩展类加载器也不做处理交给引导类加载器
引导类加载器加载属于自己的部分后交给扩展加载器
扩展类加载器加载完属于自己的部分后交给应用类加载器‘
应用类加载器加载剩余部分
’