04-Spring的注解开发

配置注解扫描

对于DI使用注解,将不再需要在Spring配置文件中声明部bean实例。Spring中使用注解,需要在原有Spring运行环境基础上在做一些改变,完成以下三个步骤:
(1)导入AOP的JAR包。因为注解的后台实现用到了AOP编程。

  • spring-aop-4.2.1.RELEASE.jar
    (2)需要更换配置文件头,即添加相应的约束:【context约束】
  • 约束在%spring_home%\docs\spring-framework-reference\html\xsd-configuration.html文件中。
    (3)需要在Spring配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

<context:component-scan base-package="com.zhy.service" />

1. 常见注解

1. @Component:定义Bean,需要在类上使用@Component,该注解的value属性用于指定该Bean的id值。

// 该注解参数省略了value属性,该属性用于指定Bena的id
@Component("myStudent")
public class Student{
    private String name;
    private int age;
}

另外:Spring还提供了3个功能基本和@Component等效的注解:
@Reposity:用于对DAO实现类进行注解【WEB层】
@Service:用于对Service实现类进行注解【业务层】
@Controller:用于对Controller实现类进行注解【持久层】
之所以创建这三个功能与@Component等效的注解,是为了以后对其进行功能上的扩展,是他们不再等效。

2. @Scope:Bean的作用域,需要在类上使用注解@Scope,其value属性用于指定作用域,默认为singleton。

@Scope(scopeName="prototype")
@Component("UserService")
public class UserServiceImpl implements IUserService{
    public void doSome(){
        System.out.println("执行doSome()……");
    }
}
  1. @Value:基本类型属性输入。需要在属性上使用注解@Value,该注解的value属性用于指定要注入的值。使用该注解完成属性注入时,类中可无需setter。当然,若属性有setter,则也可将其加到setter上。
    设置在属性上:通过反射的Field赋值,破坏了封装性。
    设置在setter上:通过setter方法赋值,推荐使用。
@Component("myStudent")
public class Student{
    @Value("张三")
    private String name;
    @Value(23);
    private int age;
    @Override
    public String toString(){
        return "Student [ name="+name+",age"+age+"]";
    }
}

3. @Autowired:自动装配,按类型byType注入域属性

需要在域属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式。使用该注解完成属性注入时,类中无需setter。当然,若属性有setter,则也可将其加到setter上。
@Autowired还有一个属性required,默认值为true。表示当匹配失败后,会终止程序运行,若将其值设置为false,则匹配失败后,将被忽略,未匹配的属性值为null。

问题:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象,从而引出了@Qualifier注解。

@Component("mySchool")
public class School{
    @Value("清华大学")
    private String name;
}
@Component("myStudent")
public class Student{
    @Value("张三")
    private String name;
    @Value(23)
    private int age;
    @Autowired
    private School school;
}

4. @Qualifier:按名称注入域属性【前提:联合@Autowired一起使用】

需要在域属性上联合使用注解@Autowired与@Qualifier。@Qualifier的value属性用于指定要匹配的Bean的id值。同样类中无需setter,也可加到setter上。
@Autowired还有一个属性required,默认值为true。表示当匹配失败后,会终止程序运行,若将其值设置为false,则匹配失败后,将被忽略,未匹配的属性值为null。

@Component("mySchool")
public class School{
    @Value("清华大学")
    private String name;
}
@Component("myStudent")
public class Student{
    @Value("张三")
    private String name;
    @Value(23)
    private int age;
    @Autowired(required=false)
    @Qualifier("mySchool")
    private School school;
}    

5. @Resource:自动装配【可按名称装配,也可按类型装配】

Spring提供了对JSR-250规范中定义@Resource标准注解的支持。@Resource注解即可以按名称匹配Bean,也可以按类型匹配Bean。使用该注解,要求JDK必须是6及以上版本。
@Resource相当于@Autowired和@Qualifier一起使用。
(1)按类型注入域属性
@Resource注解若不带任何参数,则会按照类型进行Bean的匹配注入。

@Component("mySchool")
public class School{
    @Value("清华大学")
    private String name;
}
@Component("myStudent")
public class Student{
    @Value("张三")
    private String name;
    @Value(23)
    private int age;
    @Resource
    private School school;
}

(2)按名称注入域属性
@Resource注解指定其name属性,则name的值即为按照名称进行匹配的Bean的id。

@Component("mySchool")
public class School{
    @Value("清华大学")
    private String name;
}
@Component("myStudent")
public class Student{
    @Value("张三")
    private String name;
    @Value(23)
    private int age;
    @Resource(name="mySchool")
    private School school;
}

6. @PostConstruct与@PreDestroy:Bean的声明始末

在方法上使用@PostConstruct,与原来的init-method等效。在方法上使用@PreDestroy,与destroy-method等效。

@PostConstruct
public void setUp(){
    System.out.println("Bean初始化后,执行……");
}
@PreDestroy
public void tearDown(){
    System.out.println("Bean销毁前,执行……");
}

7. 使用JavaConfing进行配置(了解)

JavaConfig是在Spring3.0开始从一个独立的项目并入到Spring中的。JavaConfig可以堪称一个用于完成Bean装配的Spring配置文件,即Spring容器,只不过该容器不是XML文件,而是由程序员使用Java自己编写的Java类。
(1)定义实体类

public class School{
    private String name;
    // setter
    // toString()
}
public class Student{
    private String name;
    private int age;
    private School school;
    // setter
    // toString()
}

(2)@Configuration/@Bean:定义JavaConfig类
对于一个POJO类,在类上使用@Configuration注解,将会使当前类作为一个Spring的容器来使用,用于完成bean的创建。
在该JavaConfig的方法上使用@Bean,将会使一个普通方法所返回的结果变为指定名称的Bean实例。
当然,在JavaConfig中,也可以完成域属性的自动注入。
A: byType方式的域属性自动注入

// 该注解表示:本类为JavaConfig
@Configuration
public class MyJavaConfig{
    // 该注解表示:方法返回的对象Bean的名称(id)为mySchool
    @Bean(name="mySchool")
    public School initialSchool(){
        return new School("清华大学");
    }
    // 采用byType自动注入school属性。当然,要求当前JavaConfig
    // 类中只能与一个方法返回值与Student的School属性具有is-a关系
    @Bean(name="myStudent",autowire=Autowire.BY_TYPE)
    public Student initialStudent(){
        return new Student("张三",23);
    }
}

B: byName方式的域属性自动注入

// 该注解表示:本类为JavaConfig
@Configuration
public class MyJavaConfig{
    // 由于Student的School属性采用byName方式,并要将这里定义的对象赋值给School属性,所以要求这里的name属性值要与School属性值相同。
    @Bean(name="mySchool")
    public School initialSchool(){
        return new School("清华大学");
    }
    // 采用byName自动注入school属性。要求School名要与JavaConfig中定义某Bean的name属性值相同。
    @Bean(name="myStudent",autowire=Autowire.BY_NAME)
    public Student initialStudent(){
        return new Student("张三",23);
    }
}
posted @ 2019-02-28 22:31  24°独家KB  阅读(152)  评论(0编辑  收藏  举报