Spring IOC容器入门(三)

2019-04-02  本文已影响0人  alexwu59

Spring IOC容器的(一)和(二)主要介绍的是Spring IOC的入门使用方法,在实际工作中,Spring通常会使用注解的方式来去掉部分或者全部xml配置,下面介绍一下在Spring中应该如何使用注解来替代xml。

根据Spring对bean对象的管理功能,它提供了四种注解:

Spring使用注解时,需要修改xml的命名空间,并且增加一个配置,告诉spring在创建容器的时候,需要到扫描的包,只有在所配置包的里面的类,spring才会去解析这些类上的注解。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
   <context:component-scan base-package="com.ws"/>
</beans>

创建bean注解

@Component(value=“test”)注解
该注解的作用就是创建一个配置了该注解的类的一个对象,把他放到spring容器中,这个对象的id就是这个test,这个注解value是可以不需要配置的,如果不配,那么默认使用类的名称,且第一个字母小写。

下面介绍一下Component注解衍生注解,这三个注解的作用和属性与Component注解一样。定义三个注解主要是更清楚的描述相应业务
@Controller 一般用在表现层
@Service 一般用在业务层
@Repository 一般用在持久层

属性注入注解

@Autowired
该注解可以用在属性上,也可以用在方法上,这个注解的原理是首先获取从spring容器中查找与需要注入属性类型相同的bean,如果找到唯一的一个bean,那么就把这个bean注入到该属性上,如果找到的两个类型符合的bean,然后接着去判断这两个类型相同的bean的id的名称哪个与需要注入的属性的名称相同,如果找到就把此bean注入到属性中,如果没有找到那么就报错,使用Autowired注解,不需要提供set方法。
@Qualifier
该注解的作用是在确定了注入类型的情况下,根据bean的ID来注入,它别和Autowired配合使用,由Autowired注解寻找类型,再由Qualifier注解寻找id,具体使用如下: Qualifier的value值表示需要把beanID=ud的bean注入到userDao属性中。

@Autowired
@Qualifier(value = "ud")
private UserDao userDao;

@Resource
由于Qualifier注解需要和Autowired配合使用,因此不方便,spring由提供了一个注解,直接安装bean的id注入。Resource注解的属性不是value而是叫name。

上面的三个注解都是只能注入bean,而基本类型和String的属性需要通过@Value注解注入,集合类型不能通过注解方式注入,只能通过xml方式。

Bean作用范围的注解

@Scope(“prototype”)
采用注解方式创建bean的默认情况下是单例,如果在类上加上@Scope(“prototype”)注解,那么创建的bean就是多例。

Bean生命周期

@PostConstruct
该注解用在方法上,表示对象创建后执行的方法
@PreDestroy
该注解用在方法上,表示bean销毁前执行的方法

上面注解引入方式仍然需要依靠xml配置文件,Spring提供了新的注解,用来替代xml文件。
@Configuration
该注解作用在java类上,表示所修饰的类是一个配置类,相当于xml文件
@ComponentScan
该注意是用来表明spring容器扫描的java包,作用相当于在xml文件配置:

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

通常两个注解配合在一起是使用。

@Configuration
@ComponentScan(basePackages = "com.ws.springtest")
public class SpringConf {

}

@Bean
在配置类中定义相应的方法,方法上加上@Bean注解,创建bean,相当于xml中定义bean标签。

@Bean(name="userService")
@Scope("prototype")
public UserService userService(){
    return new UserServiceImpl();
}

@Bean注解如果没有配置value属性,那么创建的bean就以@Bean修饰的方法的名称作为Spring IOC容器创建bean的ID,如果在@Bean修饰的方法上增加@Scope注解,可以控制创建的bean是否是单例,还是多例。
当使用注解的方法来替代xml文件的时候,那么需要调用如下的方式来启动Spring IOC容器:

ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConf.class);

SpringConf.class就是用@Configuration注解修饰的类。
-- 注意:当创建AnnotationConfigApplicationContext对象是,把SpringConf.class传入到AnnotationConfigApplicationContext时,那么SpringConf类上的@Configuration注解可以省略,因为,使用这种方式Spring会自动去读取传入到AnnotationConfigApplicationContext构造方法的类的信息,会把它当成配置类。AnnotationConfigApplicationContext的构造方法的参数是可变参数,因此可以给它传入多个配置类。只要是传入到它的构造方法中的配置类,那么都不需要在类到的上面增加@Configuration注解,此时这些配置类也不需一定要在@ComponentScan注解所扫描的包里。

@Bean注解修饰的方法如果有参数,那么参数的注入是根据参数的类型到IOC容器中寻找相关的类型的bean,注入到方法的参数中。如果在IOC容器中有类型相同的两个bean,那么就去检查方法参数的名称与哪个bean的id相同,就用哪个bean注入,否则就会报错,为了避免这种错误,可以通过@Qualifier注解来解决这个问题:

@Bean(name="userService")
public UserService userService(@Qualifier("ds1") DataSource dataSource){
    return new UserServiceImpl();
}

用@Qualifier注解来指定需要注入的bean的ID。

@Import注解
在使用代码实现spring的bean配置的时候,有时候需要创建多个配置类,每一个配置类完成相应的配置工作。那么,spring如何读取这些配置类呢?
1.把这些配置类传入到AnnotationConfigApplicationContext的构造方法中。此时这些配置类的关系是兄弟关系
2.在配置类上在增加@Configuration注解,并且该配置类必须放在@ComponentScan注解所扫描的包里
2.创建一个主配置类,在主配置类采用1或者2的方式创建,然后通过@Import注解导入其他配置类。这种方式,凡是使用@Import导入的配置类与主配置类就是个父子关系。使用@Import导入的类,既不需要配置@Configuration注解,也不需要把类放置到@ComponentScan注解所扫描的包里。

下面介绍最后两个注解:@PropertySource和@Value
该注解的作用就是读取properties文件,通过@PropertySource把相应路径下的properties文件读到spring容器中,然后通过@Value注解来获取properties文件中的相关key-value值。具体如下:

@PropertySource("classpath:jdbc.properties")
public class JDBCConf {

    @Value("${jdbc.uname}")
    private String username;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.passwd}")
    private String password;
}

其中${} 里的值是properties文件中的key。

上一篇下一篇

猜你喜欢

热点阅读