zoukankan      html  css  js  c++  java
  • @Autowired 引发的一系列思考

    关于Java注解

    注解定义

    1. 标记注解 - 没有元素
    @interface Marker {
    }
    
    1. 单元素注解 - 只有一个元素
    @interface Single {
        String value() default "name";
    }
    
    1. 普通注解 - 除了上面两种
    @interface Normal {
        String id();
        String name();
    }
    
    @interface NormalWithValue {
        String id() default "id";
        String value();
    }
    

    注解使用

    1. 标记注解 由 @Marker() 可以简化为 @Marker
    2. 按照约定,单元素注解的名称定义为 value ,这样 Single(value="123") 可以简化为 @Single("123")
    3. 对于普通注解,必须给出注解中名称以及对应的值,当然有默认值的除外,如果普通注解含有 value 名称,并且其他名称都有默认值,也可以简化为 @Normal("123")
    

    实例如下:

    @Marker
    @Single("123")
    @Normal(id = "123", name = "123")
    @NormalWithValue("123")
    class AnnotationMain {
    }
    

    Annotation Types
    Annotations

    Spring 中的注解

    1. 元注解(Meta-Annotations)
    在另一个注解上声明的注解,所以说任何一个注解都可以成为元注解
    
    在下面这个例子中,@Target、@Retention、@Documented、@Indexed都是元注解
    如果@Component又跑到别的注解头上了,那它也是元注解
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Indexed
    public @interface Component {
    }
    
    1. 角色注解(Stereotype Annotations)
    代表着一种固有的形象
    比如@Component代表组件,@Repository代表DAO,@service代表服务等等
    
    1. 组合注解(Composed Annotations)
    将一个或多个注解注解到一个注解上
    在Spring中,注解上的任何一个注解都是可以被感知到的,就代表这个注解拥有了上述几个注解的所有功能
    
    在下面这个例子中,@EnableAutoConfiguration组合了@AutoConfigurationPackage和@Import
    使用@EnableAutoConfiguration的类会被Spring认为@EnableAutoConfiguration和@AutoConfigurationPackage也是存在的
    因此@EnableAutoConfiguration就具备了@AutoConfigurationPackage的功能以及@Import的功能
    这个实现好像是通过缓存实现的,具体也不太了解,有大佬知道的可以在评论里告知一下~
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    }
    

    Spring-Annotation-Programming-Model
    MergedAnnotation-API-internals

    Spring中的 @Autowired,一个自动注入的注解

    1. 可以在构造函数中注入
    @Service
    @Getter
    public class MyService1 {
        private MyDao1 myDao1;
    
        @Autowired
        public MyService1(MyDao1 myDao1) {
            this.myDao1 = myDao1;
        }
    }
    
    1. 可以在方法中注入
    Spring 会自动自动执行方法,并把myDao注入住到方法参数里面
    
    @Getter
    public class MyService2 {
        private MyDao1 myDao1;
        private MyDao2 myDao2;
    
        @Autowired
        public void setMyDao1(MyDao1 myDao1) {
            this.myDao1 = myDao1;
        }
    
        @Autowired
        public void fun(MyDao2 myDao2) {
            this.myDao2 = myDao2;
        }
    }
    
    1. 也可以在属性上注入
    @Getter
    public class MyService3 {
        @Autowired
        private MyDao1 myDao1;
    }
    
    1. 也可以混合注入
    @Getter
    public class MyService4 {
        @Autowired
        private MyDao1 myDao1;
        private MyDao2 myDao2;
        private MyDao3 myDao3;
    
        @Autowired
        public void fun(MyDao2 myDao2) {
            this.myDao2 = myDao2;
        }
    
        @Autowired
        public MyService4(MyDao3 myDao3) {
            this.myDao3 = myDao3;
        }
    }
    
    1. 其他注意的地方
    • 使用@Autowired时,容器里必须要存在这个类型的实例的,如果没有就会报错,如果不是必须要注入此类,可以将required设置为false,默认为true
    @Getter
    public class MyService5 {
        private MyDao1 myDao1;
    
        @Autowired(required = false)
        public MyService5(MyDao1 myDao1) {
            this.myDao1 = myDao1;
        }
    }
    
    • 如果在多个构造函数上使用@Autowired,则所有的@Autowired必须将required设置为false,将会选一个参数较多的构造函数进行注入
    @Getter
    public class MyService6 {
        private MyDao1 myDao1;
        private MyDao2 myDao2;
    
        @Autowired(required = false)
        public MyService6() {
        }
    
        @Autowired(required = false)
        public MyService6(MyDao1 myDao1) {
            this.myDao1 = myDao1;
        }
    
        @Autowired(required = false)
        public MyService6(MyDao2 myDao2) {
            this.myDao2 = myDao2;
        }
    }
    
    • 如果只有一个构造函数,不用加@Autowired也会自动注入,下面的例子中的所有属性将会注入
    @Getter
    public class MyService6 {
        private MyDao1 myDao1;
        private MyDao2 myDao2;
    
        public MyService6(MyDao1 myDao1, MyDao2 myDao2) {
            this.myDao1 = myDao1;
            this.myDao2 = myDao2;
        }
    }
    

    beans-autowired-annotation

    使用Java编程获取Spring bean

    • @Bean 用于标记一个bean 定义
    • @Configuration 里面有很多 @Bean 标记的方法
    public class MyDao {
    }
    
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    public class MyService {
        private MyDao myDao;
    }
    
    @Configuration
    public class AppConfig {
        
        @Bean
        public MyService myService(MyDao myDao) {
            return new MyService(myDao);
        }
    
        @Bean
        public MyDao myDao() {
            return new MyDao();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
            MyService myService = applicationContext.getBean(MyService.class);
            MyDao myDao = applicationContext.getBean(MyDao.class);
            System.out.println(myService.getMyDao() == myDao);
        }
    }
    
    输出:
    true
    说明 myService不为null,myDao不为null,myDao已经被注入到myService中
    

    Java-based Container Configuration

  • 相关阅读:
    VIM配置
    VSCode配置Import@路径
    Sar
    VIM-Fold折叠
    sysctl
    java8 到 java14新增的特性
    Electron整合VUE
    使用Markfile开发GO程序
    cron 表达式
    java spi
  • 原文地址:https://www.cnblogs.com/eaglelihh/p/13264246.html
Copyright © 2011-2022 走看看