美文网首页
动态代理,注解

动态代理,注解

作者: 达摩君 | 来源:发表于2017-12-13 21:22 被阅读67次

代理模式

  • 什么是代理模式及其作用
    Proxy Pattern(即:代理模式),23种常用的面向对象软件的设计模式之一
    代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
    优点:
    (1).职责清晰
    真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
    (2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
    (3).高扩展性
    结构
    一个是真正的你要访问的对象(目标类),另一个是代理对象,真正对象与代理
    对象实现同一个接口,先访问代理类再访问真正要访问的对象。

动态代理

动态代理它可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在。
动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。
动态代理生成技术:
1.jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象。
2.cglib (spring学习)

Java.lang.reflect.Proxy类可以直接生成一个代理对象

Proxy.newProxyInstance():产生代理类的实例。仅能代理实现至少一个接口的类
ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。
Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。
InvocationHandler:策略(方案)设计模式的应用。如何代理?

InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行
Object proxy:代理对象本身的引用。一般用不着。
Method method:当前调用的方法。
Object[] args:当前方法用到的参数

public class XMQ {
    public static void main(String[] args) {
        final DoSome sd = new PJL();
        DoSome o = (DoSome) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(sd, null);
            }
        });
        o.dosomething();
    }
}

注解

它不是注释 注释是程序员写的,给程序员的
注解给程序看,用于描述程序如何运行及在什么阶段来运行。
注解现在在实际开发中,最大的功能是用于替换配置文件。
注解是jdk1.5的新特性
可以通过反射来让注解具有功能。
注解 @xxxx

自定义注解

1、JDK中的三个基本的注解

a、@Override:检查子类确实是覆盖了父类的方法。
b、@Deprecated:说明已经过时了。
c、@SuppressWarnings({ "unused", "deprecation" }):抑制程序中的警告。unused警告的类型。{}数组。all抑制所有警告。

2、自定义注解的语法

研究一下注解的本质
声明一个注解 @interface 注解名{}

public @interface MyAnnotation{}

注解它的本质就是一个接口,这个接口需要继承 Annotation接口。
public interface MyAnnotation extends java.lang.annotation.Annotation {
}
分析注解中的成员
注解本质上就是接口,接口中可以有属性方法
属性 : 例:int age();

关于注解的属性类型可以有哪些?
1.基本类型
2.String
3.枚举类型
4.注解类型
5.Class类型
6.以上类型的一维数组类型

public @interface Ann1 {
    
    int age();
    String name() default "";
    Class clazz() default Object.class;
}
public class Ann2 {
    //属性没有默认值,必须赋值
    @Ann1(age = 10)
    void dododo() {
        System.out.println("呵呵");
    }
}

注解:就是在你的程序代码中的某个位置加了一个标记而已

注释的反射

a、反射注解类

java.lang.reflect.AnnotatedElement:
<T extends Annotation> T getAnnotation(Class<T> annotationType):得到指定类型的注解引用。没有返回null。
Annotation[] getAnnotations():得到所有的注解,包含从父类继承下来的。
Annotation[] getDeclaredAnnotations():得到自己身上的注解。
boolean isAnnotationPresent(Class<? extends Annotation> annotationType):判断指定的注解有没有。

Class、Method、Field、Constructor等实现了AnnotatedElement接口.
如果:Class.isAnnotationPresent(MyTest.class):判断类上面有没有@MyTest注解;
Method.isAnnotationPresent(MyTest.class):判断方法上面有没有@MyTest注解。

b、反射注解中的属性
public class TestRunner {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {

        Class clazz = Ann2.class;
        Method[] methods = clazz.getMethods();
        for (Method m:
             methods) {
            System.out.println(m.getName());
            //得到当前方法上的注解对象
            Ann1 ann1 = m.getAnnotation(Ann1.class);
            if (ann1 != null) {
                long timeout = ann1.timeout();
                if (timeout < 0) {
                    //表示不需要测试
                    m.invoke(clazz.newInstance(), null);
                } else {
                    //需要测试
                    long l1 = System.nanoTime();
                    m.invoke(clazz.newInstance(),null);
                    long l2 = System.nanoTime();
                    if ((l2 - l1) > timeout) {
                        System.out.println(m.getName() + "方法超时");
                    }
                }
            }
        }
    }
}
@Ann1
public class Ann2 {
    //属性没有默认值,必须赋值
    @Ann1(timeout = 111)
    public void dododo() {
        System.out.println("呵呵");
    }

    @Ann1(timeout = 1000)
    public void test() {
        System.out.println("test");
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
@Inherited
public @interface Ann1 {

    int age() default 1;
    String name() default "";
    Class clazz() default Object.class;
    int timeout() default -1;
}

元注解

什么是元注解:
只能用在注解上的注解叫做元注解。(即:用于修饰注解的注解)

  • 自定义的注解的存活范围(生命周期):默认是CLASS。
  • @Retention:作用。改变自定义的注解的存活范围。
    RetentionPolicy:
    SOURCE
    CLASS
    RUNTIME
  • @Target:作用,指定该注解能用在什么地方。
    ElementType:
    TYPE:
    METHOD:
    FIELD:
    ANNOTATION_TYPE
  • @Documented:作用,使用了@MyTest的注解的类,如果@MyTest注解上面有@Documented注解,那么使用了@MyTest的注解的类的API文档中会出现@MyTest的身影。
  • @Inherited:作用,说明该注解可以被继承下去。

相关文章

  • Java 代理

    静态代理 动态代理 动态代理, 日志切片使用反射获得方法 动态代理, 自定义注解(对注解的方法,使用动态代理添加切...

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

  • retrofir

    注解 + 动态代理+反射+ okhttp

  • web25 动态代理 注解

    注解有特殊功能都是runtime级别的 注解三步:定义,使用,解析 动态代理也可增强,但一般用于拦截 动态代理必须...

  • spring aop 汇总

    静态代理、动态代理和cglib代理 aop 使用 Spring AOP - 注解方式使用介绍spring aop ...

  • 动态代理,注解

    代理模式 什么是代理模式及其作用Proxy Pattern(即:代理模式),23种常用的面向对象软件的设计模式之一...

  • JDK1.8里Method.invoke()的实现原理

    简介 上一篇文章[java注解研究]提到注解最终通过生成动态代理实现类方式来调用,而动态代理实际就是通过反射来调用...

  • 从注解动态代理理解Retrofit对OkHttp的封装,手写实现

    仅实现Retrofit中的注解和动态代理 大概流程:1.通过动态代理实例化接口2.每调用一个方法都会调用到动态代理...

  • Android-自定义注解-Java动态代理(Proxy)-动态

    我们一路从java注解基础,元注解、自定义注解、反射、代理【动态代理】模式一路到现在,基本上可以针对Android...

  • 注解反射以及动态代理

    注解与反射以及动态代理 注解 注解的定义 Annotation(注解)就是Java提供了一种元程序中的元素关联任何...

网友评论

      本文标题:动态代理,注解

      本文链接:https://www.haomeiwen.com/subject/ixgnixtx.html