基础加强:类加载器 ---注解 ---动态代理(装饰设计模式)

来源:互联网 发布:工程动画软件 编辑:程序博客网 时间:2024/05/17 07:18
基础加强
1.类加载器
2.注解
3.动态代理(装饰设计模式)

1.类加载器,作用?
见图1,2


图1


图2


 怎么获取类加载器?(重点)
     ClassLoader  字节码对象.getClassLoader()


2.注解
   1.什么是注解,注解作用?
注解就是符合一定格式的语法 @xxx
注解的作用:
注释:在阅读程序的时候清楚-给程序员看的。
注解:给JVM看,给机器的。

注解在目前而言最主流的应用 :代替配置文件
注解优点:开发效率高  成本低
注解缺点:耦合性大  不利于后期维护


   2.jdk5提供的注解
@Override:告知编译器此方法是覆盖父类的方法 
@Deprecated:标注方法过时
@SuppressWarnings:压制警告
注意:
不同的注解只能在不同的位置使用(方法上,字段上,类上)


    @interface   class  interface   ()  {}  []  <>

   3.自定义注解(了解)
1)怎么样去编写一个自定义的注解
2)怎么样去使用注解
3) 怎么样去解析注解--使用反射知识


(1)编写一个注解
关键字:@interface
注解的属性:
语法:返回值 名称()
注意:如果属性的名字是value,并且注解的属性值只有一个,那么在使用注解时可以省略value


注解属性类型只能是以下几种:
1.基本类型
2.String
3.枚举类型  enum
4.注解类型
5.Class类型
6.以上类型的一维数组类型
(2)使用
//@MyAnno(name = "aa")
(3)解析使用了注解的类
元注解:代表修饰注解的注解  限制定义的注解的特性。
@Target
代表注解修饰的范围:类上使用,方法上使用,字段上使用。
FILED:字段上可用此注解
METHOD:方法上可用此注解
TYPE:为/接口上可以使用此注解
@Retention
SOURCE:注解在源码级别可见
CLASS:注解在字节码文件级别可见
RUNTIME:注解在整个运行阶段都可见



3.动态代理
1.代理(中介):
 目标对象/被代理对象----房主:真正的租房的方法
 代理对象---中介:出租的方法(调用房主的出租的方法)
 执行代理对象方法的对象:---租房的人


 流程:我们要租房--->中介(租房的方法)-->房东(租房的方法)
 抽象:调用对象-->代理对象--->目标对象


 结构:
接口 method();
         |--目标对象  method()

   |--代理对象  method()


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


动态代理的API
 newProxyInstance()
ClassLoder
Class<?>[] interface
InvocationHandler
返回值 Object就是代理对象


注意:JDK的Proxy方式实现动态代理时目标对象必须有接口
没有接口不能实现jdk版动态代理。

 

package com.huida.proxy;public class Target  implements TargetInterface{@Overridepublic void method1() {System.out.println("method1 run...1");}@Overridepublic String method2() {return "hello";}public String method3(String str) {return str;}}
 

package com.huida.proxy;public interface TargetInterface{public void method1();public String method2();public String method3(String str);}


动态代理格式1

package com.huida.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProTest {public static void main(String[] args) {//获得动态的代理对象,在运行时在内存中动态的为Target创建一个虚拟的代理对象//loader与目标对象相同的类加载器Target.class.getClassLoader()TargetInterface objectproxy = (TargetInterface)Proxy.newProxyInstance(Target.class.getClassLoader(), new Class[]{TargetInterface.class},new InvocationHandler() {//Object proxy代理对象, Method method目标对象的方法字节码对象, //Object[] args目标对象的响应的方法参数@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("目标对象方法执行前的引用");//代理对象的引用Object invoke = method.invoke(new Target(), args);System.out.println("目标对象方法执行后的引用---2");return invoke;}});objectproxy.method1();String string = objectproxy.method2();System.out.println(string);}}

动态代理格式2

package com.huida.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyTest2 {public static void main(String[] args) {    //创建目标对象Target target=new Target();//动态创建代理对象TargetInterface proxy=(TargetInterface)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler() {//Object proxy代理对象, Method method目标对象的方法字节码对象, //Object[] args目标对象的响应的方法参数@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object invoke = method.invoke(target, args);return invoke;}});proxy.method1();//调用invoke--method1() null  nullString method2 = proxy.method2();//调用invoke--method2() null  StringSystem.out.println(method2);String method3 = proxy.method3("hello world");//调用invoke--method3() String(参数)  String(返回值)System.out.println(method3);}}

动态代理格式3

package com.huida.reflect;import java.io.FileInputStream;import java.lang.reflect.Method;import java.util.Collection;import java.util.Iterator;import java.util.Properties;public class MainBoard {public static void main(String[] args) throws Exception {System.out.println("主板运行了。。。");/*VoiceCard vc=new VoiceCard();useCard(vc);NetCard nc=new NetCard();useCard(nc);ShowCard sc=new ShowCard();useCard(sc);*/FileInputStream fis=new FileInputStream("src/config.properties");if (fis!=null) {Properties props=new Properties();props.load(fis);Collection collection = props.values();//System.out.println(collection);Iterator iterator = collection.iterator();while (iterator.hasNext()) {//System.out.println(iterator.next());Class class1=Class.forName((String) iterator.next());Method method1 = class1.getMethod("open", null);method1.invoke(class1.newInstance(), null);Method method2 = class1.getMethod("close", null);method2.invoke(class1.newInstance(), null);}}System.out.println("主板停止运行了。。。");}/*public static void useCard(VoiceCard vc) {vc.open();vc.close();}public static void useCard(NetCard nc) {nc.open();nc.close();}*/public static void useCard(Card c) {c.open();c.close();}}


4.装修设计模式(静态代理):对原有的对象的方法进行增强
Animal   eat()  吃饱
 |--Dog  eat() 吃好
   |--SuperDog eat() 吃健康

BufferedInputStream bis = new BufferedInputStream(newFileInputStream());

Person
  |--Man
  |--SuperMan

  |--FlyMan


装饰模式(Decorator)

1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

2.    装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任。换言之客户端并不会觉的对象在装饰前和装饰后有什么区别。

3.    装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展

4.    装饰模式与类继承的区别:

1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

2)    装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加两个方法。

3)    装饰与继承比较图:

4)    装饰模式是在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,它是通过创建一个包装对象,也就是装饰来包裹真是的对象。

5.    装饰模式把对客户端的调用委派给被装饰的类,装饰模式的关键在于这种扩展完全透明的。

 

 

6.    装饰模式的构成:

1)    抽象构建角色(Component):给出一个抽象的接口,以规范准备接受附加责任的对象。相当于i/o流里面InputStream/OutputStreamReader/Writer

2)    具体的构建角色(ConcreteComponent):定义一个将要接受附加责任的类。相当于i/o里面的FileOutputStreamFileInputStream

3)    装饰角色(Docorator):持有一个抽象构建(Component)角色的引用,并定义一个与抽象构件一致的接口。相当于i/o里面的FilerOutputStreamFilterInputStream

4)    具体的装饰角色(ConcreteDecorator):负责给构建对象“贴上”附加的责任。相当于i/o流里面的BufferedOutputStreamBufferedInputStream以及DataOutputStreamDataInputSrtream

7.    装饰模式的特点:

1)    装饰对象和真实对象具有相同的接口,这样客户端对象就可以以真实对象的相同的方式和装饰对象交互。

2)    装饰对象包含一个真实对象的引用(reference).

3)    装饰对象接受所有来自客户端的请求,它把这些请求转发给真实的对象。

4)    装饰对象可以在转发这些请求以前或者以后增加一些附加的功能。这样就能确保在运行时,不用修改给定对象结构就可以在外部增加附加的功能。在面向对象的程序设计中,通常是使用继承的关系来扩展给定类的功能。


5.电脑


阅读全文
0 0