美文网首页springjs css html
[3]Spring 5 注解编程基础组件-赋值类注解

[3]Spring 5 注解编程基础组件-赋值类注解

作者: AC编程 | 来源:发表于2022-09-09 10:16 被阅读0次

    连载地址

    总览、赋值组件 Injection Components

    赋值组件

    一、@Component 注解

    1.1 功能说明

    泛指组件,当组件不好归类的时候,使用这个注解进行标注

    1.2 要点说明

    从源码可以看出,@Service@Repository@ControllerConfiguration等组件都是@Component组件的一种,他们都使用了@Component组件。

    1.3 源码

    @Component注解源码

    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Indexed
    public @interface Component {
        String value() default "";
    }
    
    1.4 demo
    @Component
    public class MyConponent {
    
        //声明这个类需要被注册到IOC容器中
    }
    

    二、@Service 注解

    2.1 功能说明

    用于标注业务层组件

    2.2 源码
    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.core.annotation.AliasFor;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Service {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    }
    
    2.3 demo
    @Service
    public class MyService {
    
        //如果是业务层组件,则用此注解,同样会被注册到IOC容器中
    }
    

    三、@Controller 注解

    3.1 功能说明

    用于标注控制层组件

    3.2 源码
    package org.springframework.stereotype;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.core.annotation.AliasFor;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Controller {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    }
    
    3.3 demo
    @Controller
    public class MyController {
    
        // 如果是控制层组件,则用此注解,同样会被注册到IOC容器中
    }
    

    四、@Repository 注解

    4.1 功能说明

    用于标注数据访问层组件,即DAO组件

    4.2 源码
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Repository {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    }
    
    4.3 demo
    @Repository
    public class MyDao {
    
        // 如果是数据访问层组件,则用此注解,同样会被注册到IOC容器中
    }
    

    五、@Value 注解

    5.1 功能说明

    普通数据类型赋值

    5.2 要点说明

    三种使用@Value的方式给属性赋值:

    • 直接赋值
    • 获取配置文件属性
    • EL表达式
    5.3 源码
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Value {
        String value();
    }
    
    5.4 demo
    5.4.1 代码
    @Component
    public class Player {
    
        //支持基本数据类型
        @Value("AlanChen")
        private String name;
    
        //通过@PropertySource("classpath:values.properties")读取配置文件取值
        @Value("${player.address}")
        private String address;
    
        //支持Spring EL表达式
        @Value("#{2022-1990}")
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Player{" +
                    "name='" + name + '\'' +
                    ", address='" + address + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    @Configuration
    @ComponentScan
    @PropertySource("classpath:values.properties")
    public class MyConfig {
        // @ComponentScan注解在某类上时会扫描该类所在包下的所有类
    }
    
    public class MyTest {
    
        @Test
        public void test(){
            ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class);
    
            Player player = app.getBean(Player.class);
            System.out.println(player);
        }
    }
    

    resources/values.properties

    player.address=Zhu Hai
    
    5.4.2 运行结果
    Player{name='AlanChen', address='Zhu Hai', age=32}
    

    六、@PropertySource 注解

    6.1 功能说明

    读取配置文件赋值

    6.2 源码
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Repeatable(PropertySources.class)
    public @interface PropertySource {
    
        String name() default "";
    
        String[] value();
    
        boolean ignoreResourceNotFound() default false;
    
        String encoding() default "";
    
        Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
    }
    
    6.3 demo
    6.3.1 代码
    @Configuration
    @ComponentScan
    @PropertySource("classpath:values.properties")
    public class MyPropertySourceConfig {
        // @ComponentScan注解在某类上时会扫描该类所在包下的所有类
    }
    
    public class MyTest {
    
        @Test
        public void test() {
            ApplicationContext app = new AnnotationConfigApplicationContext(MyPropertySourceConfig.class);
            System.out.println("IoC容器创建完成");
    
            // 从环境变量中取值
            Environment env = app.getEnvironment();
            String address = env.getProperty("player.address");
            System.out.println(address);
        }
    }
    
    6.3.2 运行结果
    IoC容器创建完成
    Zhu Hai
    

    七、@Autowired 注解

    7.1 功能说明

    用来完成组件的装配,可以结合@Qualifier注解一起使用组件的装配。

    7.2 要点说明
    • @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired
    • 默认按byType自动注入,是Spring的注解。
    • 默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,@Autowired(required = false)。
    • 按类型装配的过程中,如果发现找到多个bean,则又按照byName方式进行比对,如果还有多个,则报出异常。
    7.3 源码
    package org.springframework.beans.factory.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
        boolean required() default true;
    }
    
    7.4 demo
    @Repository
    public class UserDao {
    
    }
    
    @Service
    public class UserService {
    
        @Autowired
        private UserDao userDao;
    }
    

    八、@Qualifier 注解

    8.1 功能说明

    如存在多个实例,配合@Autowired使用,优先级高于@Autowired,但是无法单独使用。如存在多个实例,配合使用,优先级高于@Autowired

    8.2 源码
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface Qualifier {
        String value() default "";
    }
    
    8.3 demo
    @Repository("dao")
    public class StudentDao {
    
    }
    
    @Service
    public class StudentService {
    
        @Qualifier("dao")
        @Autowired
        private StudentDao studentDao;
    }
    

    九、@Primary 注解

    9.1 功能说明

    如果Spring容器中存在多个相同名字的Bean,使用@Primary注解可以提高优先级,成为首选者,否则报错。

    9.2 源码
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Primary {
    
    }
    
    9.3 demo
    9.3.1 代码
    public class SchoolComponent {
    
        private String name;
    
        public SchoolComponent() {
        }
    
        public SchoolComponent(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "SchoolComponent{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    @Configuration
    @ComponentScan
    public class MyPrimaryConfig {
    
        //使用当前实例
        @Primary
        @Bean("schoolComponent")
        public SchoolComponent schoolComponent() {
            return new SchoolComponent("清华");
        }
    
        @Bean("schoolComponent")
        public SchoolComponent schoolComponent2() {
            return new SchoolComponent("北大");
        }
    }
    
    public class MyTest {
    
        @Test
        public void test(){
            ApplicationContext app = new AnnotationConfigApplicationContext(MyPrimaryConfig.class);
    
            Object bean = app.getBean("schoolComponent");
            System.out.println(bean);
        }
    }
    
    9.3.2 运行结果
    SchoolComponent{name='清华'}
    

    十、@Resource 注解

    10.1 功能说明

    用来完成组件的装配,可以单独使用,优先级更高。

    10.2 要点说明
    • @Resource是javaEE的注解,它遵循的是JSR-250规范,需要导入包javax.annotation.Resource

    • 默认按照byName方式进行装配,属于J2EE自带注解,没有指定name时,name指的是变量名。

    • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

    • 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

    • 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。

    • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配。如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

    10.3 源码
    package javax.annotation;
    
    import java.lang.annotation.*;
    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.*;
    
    @Target({TYPE, FIELD, METHOD})
    @Retention(RUNTIME)
    public @interface Resource {
    
        String name() default "";
        
        String lookup() default "";
        
        Class<?> type() default java.lang.Object.class;
        
        enum AuthenticationType {
            CONTAINER,
            APPLICATION
        }
        
        AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
        
        boolean shareable() default true;
        
        String mappedName() default "";
        
        String description() default "";
    }
    
    10.4 demo
    @Repository("addressDao")
    public class UserAddressDao {
        
    }
    
    @Service
    public class UserAddressService {
    
        @Resource(name = "address")
        private UserAddressDao userAddressDao;
    }
    

    相关文章

      网友评论

        本文标题:[3]Spring 5 注解编程基础组件-赋值类注解

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