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

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/eaglelihh/p/13264246.html
Copyright © 2011-2022 走看看