android中的代理、注解

什么是代理模式?
作用:为对象提供一种代理控制对对象的访问

代理模式的好处?
不想或者是不能直接引用访问另一个对象 代理对象可以在目标和使用者之间起到中介作用

代理模式涉及的角色
抽象角色 声明真实对象和代理对象共同的接口
代理角色 代理角色对象的内部都持有真实的对象的引用 操作真实的对象
真实角色 代理角色所代表的角色

调用方法通过经纪人访问明星

静态代理

一般在编码时就确定了代理和被代理的对象关系 如果运行时才确定的代理行为 静态代理不合适
静态代理的弊端
1.在运行前就需要手动创建代理类 代理类较多时比较麻烦
2.代理类和被代理类必须实现共同的接口 接口变动 代理类和被代理类需要修改代码

动态代理

public class Test {
    public static void main(String[] args) {
//      Star star=new Star("wangbaoqiang");
//      Angent angent=new Angent(star);
//      angent.movieShow(300000000);
//      angent.tvShow(2000000000);

        Star star=new Star("wangbaoqiang");
        ProxyHandler handler=new ProxyHandler(star);
        IMovieStar angent=(IMovieStar) handler.getProxy();//通过动态代理类生成动态代理的对象
        angent.movieShow(30000000);
        angent.tvShow(100);
    }

}
public class ProxyHandler implements InvocationHandler{
    //持有被代理对象的引用
    private Object target;
    public ProxyHandler(Object target){
        this.target=target;
    }
    /**
     * 方法的拦截 可以根据method的名称创建类信息进行处理
     * Method method, 拦截的方法   
     * Object[] args 方法对应的参数 
     * 
     * x.class().method("tvShow",int.class)
     * method.invoke(x,1000000);
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        String methodName=method.getName();//获取拦截处理的方法的名称
        if(methodName.equals("movieShow") ||methodName.equals("tvShow")){
            if(args[0] instanceof Integer && ((Integer)args[0])<10000000){
                System.out.println(args[0]+"钱太少!找xxx去吧");
                return null;
            }
        }
        Object result=method.invoke(target,args);
        return result;
    }
    //Proxy.newProxyInstance() 生成代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }
    /*
     * 
     *  public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler i){
     *  }
     *  ClassLoader loader,   被代理类的加载器 用来创建代理类
     *  Class<?>[] interfaces, 被代理类实现的接口 创建的代理类都实现接口
     *  InvocationHandler i  关键 它的类中具有唯一的invoke方法 代理类进行拦截操作的函数 
     */

}
注解:

标注解释的标记 加了注解的程序存在标记 通过反射获取字节码文件对象读取类中的成员(构造函数 变量 函数 类成员上标记)
标记可以添加在包 类 变量 方法

@Override 重写父类或者父接口中的方法
@Deprecated 类或者成员过时
@SuppressWarnings 排除警告
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)//当前的注解可以标记在成员变量 对象 属性
public @interface AnnotationName {//@AnnotationName()
//声明注解的属性
String value() default “Hello”; //value=”qq”
}

public class TestAnnotation {
    @AnnotationName("zhangsan")// value="qq"
    public String info;//使用注解的形式info赋值

    public static void main(String[] args) {
        TestAnnotation ta=new TestAnnotation();
        parserAnnotation(ta);
        System.out.println(ta.info);//  qq
    }
    /**
     * 定义解释注解的方法
     * @param ta
     */
    public static void parserAnnotation(TestAnnotation ta){
        try {
            //根据类的对象获取类的字节码文件对象
            Class clazz=ta.getClass();
            //根据字节码文件对象指定类中的变量的名称获取变量
            Field field=clazz.getField("info");
            //获取info字段上的注解
            Annotation[] annotations=field.getDeclaredAnnotations();
            //info字段上存在注解
            if(annotations!=null && annotations.length!=0){
                Annotation an=annotations[0];//获取属性中的第一个注解
                //获取注解的名称
                String name=an.annotationType().getName();
                System.out.println("注解的名称--------"+name);
                if(name.equals(AnnotationName.class.getName())){
                    AnnotationName anName=(AnnotationName) an;
                    //set(表示给那个对象的属性赋值,表示赋值的内容) 将注解的value的值赋值给ta对象的info
                    field.set(ta, anName.value());//new TestAnnotation().info="qq"
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}

注解以@interface关键字来定义 声明元注解(注解的注解 标示注解的生命周期 使用位置等)

@Retention 元注解 表示需要在什么级别保存该注解信息(生命周期)
RetentionPolicy.RUNTIME 表示虚拟机运行时保留注解
RetentionPolicy.SOURCE 表示停留在java源文件
RetentionPolicy.CLASS 停留在class文件中 默认
@Target元注解 表示该注解用于什么地方(类 方法 变量)
@Documented 元注解 将注解包含在javadoc中
@Inherited 元注解 允许子类继承父类中的注解

定义注解的步骤:
1.以@interface创建注解文件
2.声明元注解@Retention和@Target
3.声明注解的属性和默认值
4.使用解析注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)//当前的注解可以标记在成员变量 对象 属性
public @interface AnnotationName {//@AnnotationName()
//声明注解的属性
String value() default “Hello”;
}

public class AnnotationName{
String value=”Hello”;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值