zoukankan      html  css  js  c++  java
  • 注解和依赖注入框架

    注解和依赖注入框架

    在开始之前,带着几个问题去看:

    1. 什么是注解?
    2. 注解有什么作用?
    3. 如何使用注解?
    4. 注解的应用场景?
     
    注解.png

    一、注解及其作用

    注解是在JDK 1.5之后引入的,是代码中的特殊标记(以“@注解名”)存在,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。引用Java编程思想里的描述:注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。


    二、注解的分类

    可以看上面导图,这里对几个元注解做一下简单说明

    • @Targe:注解所修饰的对象范围。该值是一个ElementType类型的数组,可取值有FILED METHOD等
    • @Retention:用于声明注解的保留策略,可取值有:RetentionPolicy.SOURCE CLASS和RUNTIME,分别表示源码级,编译时和运行时注解;运行时注解可以通过反射来获取该注解信息。

    三、使用

    3.1 定义注解
    下面是一个自定义注解的例子

    // 表示该注解为运行时注解,可根据需要设置其为其他两种类型
    @Retention(RetentionPolicy.RUNTIME)
    // 定义新的注解,使用@interface关键字
    public @interface Student {
    
        // 注解中只有成员变量,没有方法
        // 定义成员变量,为下面这种无参方法的形式
        // 可以使用default关键字为其指定默认值
        String name() default "Joey";
    
        int age() default 20;
    }
    
    // 如果定义了成员变量,使用该注解时,就必须为其指定值
    //(定义了default值的情况除外)
    @Student(name = "K", age = "21")
    public void test() {
    
    }
    

    关于@Retention值的选择:
    如果只是做一些检查操作,则使用SOURCE;
    如果编译时预处理,例如生成辅助代码,则选择CLASS;
    如果运行时动态获取注解信息,则选择RUNTIME

    3.2 注解处理器
    注解必须配合注解处理器才能有作用,下面是注解处理器实现的一般方法:

    • 针对运行时注解,采用反射机制
    • 编译时注解,采用AbstractProcessor处理
      下面分别看一下:
    1. 运行时注解
      还是用上面的例子,
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Student {
        String name() default "Joey";
    
        int age() default 20;
    }
    
    public class AnnotationTest {
        @Student(name = "K", age = "21")
        public void test() {
    
        }   
    }
    
    // 下面是一个简单的注解处理器
    public class AnnotationProcessor {
        public static void main(String[] args) {
            Method[] methods = AnnotationTest.class.getDeclaredMethods();
            for (Method m: methods) {
                Student student = m.getAnnotion(Student.class);
                System.out.println(student.name() + " " + student.age());
            }
        }
    }
    

    getDeclaredMethods和getAnnotion方法都属于AnnotatedElement接口,Class,Method和Filed类都实现了该接口

    1. 编译时注解处理器

    四、依赖注入

    控制反转(Ioc):即Inversion of Control,用于实现对象间的解耦;指的是借助第三方实现具有依赖关系的对象之间的解耦;
    举个例子,假设A和B对象相互依赖,那么当A在运行至某一点时,会主动去创建B的对象或者使用以及创建好的对象B,此时主动权在A手上;当加入IOC对象后,A与B之间失去了直接的联系,当A需要B时,IOC容器会主动创建一个B对象注入A需要的地方。可见,A创建B的过程由主动变为被动,就是控制反转的意思

    依赖注入(DI):即Dependency Injection,值IoC容器运行期间,动态的将某种依赖关系注入到对象中。
    依赖注入的实现方法:
    这里举一个例子:
    当代码中需要依赖其他类时,我们可能会这么写

    public class Car {
        private Engine engine;
    
        public Car() {
            engine = new ConcreteEngine();
        }
    }
    

    这种方法存在的问题就是耦合度太高,car中需要知道具体的engine实现类,即ConcreteEngine类,一旦engine类型更改,car的构造方法也需要修改
    将上面代码改为依赖注入的方法:

    public class Car {
        private Engine engine;
    
        public Car(Engine engine) {
            this.engine = engine;
        }
    }
    

    这样一来,Car无需关心Engine的实现,即使后者类型变化了,Car也不需要做任何修改
    一些简单的依赖注入方法有:

    构造方法注入
    Setter方法注入
    接口注入

  • 相关阅读:
    应用程序池的配置 狼
    SQL跨数据库复制表数据 狼
    <script language= "javascript " for= "window " event= "onload "> 狼
    禁止虚拟目录继承根目录下web.config中的有些配置 web.config的继承禁止方法 狼
    linux 在程序里修改系统时间
    xlinux下载地址
    安装tslib1.4出现的问题汇总
    linux之看门狗 (转)
    VC中显示GIF图片
    mdev 自动挂载U盘成功
  • 原文地址:https://www.cnblogs.com/isme-zjh/p/11378422.html
Copyright © 2011-2022 走看看