spring IoC回顾(将Bean 装配到Ioc容器中)

spring IoC(控制反转)

在Spring中把每一个需要管理的对象称为Spring Bean (简称Bean ),而Spring 管理这些Bean 的容器,被我们称为Spring
IoC 容器(或者简称IoC 容器) 。IoC 容器需要具备两个基本的功能:
通过描述管理Bean , 包括发布和获取Bean;

通过描述完成Bean 之间的依赖关系。

Spring IoC 容器是一个管理Bean 的容器,在Spring 的定义中,它要求所有的IoC 容器都需要实现接口BeanFactory ,它是一个顶级容器接口。由于BeanFactory 的功能还不够强大,因此Spring 在BeanFactory 的基础上, 还设计了一个更为高级的接口ApplicationContext 。它是BeanFactory 的子接口之一, 在Spring 的体系中BeanFactory 和ApplicationContext 是最为重要的接口设计,在现实中我们使用的大部分Spring IoC 容器是Appl icationContext 接口的实现类。

下面来看一个最为简单的例子。首先定义一个Java 简单对象( P lain Ordinary Java Object, POJO )文件User.java

package com.springboot.chapter3.pojo;

public class User{

  private Long id;

  private String userName;

  private String note;

}

然后再定义一个Java 配置文件AppConfig.java

package com.springboot.chapter3.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration ;
import com.springboot.chapter3.pojo.User ;

@Configuration

public class AppConfig{

  @Bean(name="user")

  public User initUser(){

    User user = new User();

    user.setId(1L);

    user.setUserName("username");

    user.setNote("note");

    return user;   

  }

}

@ Configuration 代表这是一个Java 配置文件, Spring的容器会根据
它来生成IoC 容器去装配Bean; @Bean 代表将initUser方法返回的POJO 装配到IoC 容器中,而其
属性name 定义这个Bean 的名称,如果没有配置它,则将方法名称“ initUser ”作为Bean 的名称保
存到Spring IoC 容器中。

做好了这些,就可以使用AnnotationConfigApplicationContext 来构建自己的IoC 容器

package com.springboot.chapter3.config ;
import org.apache.log4j.Logger ;
import org.springframework.context.ApplicationContext ;
import org.springframework.context annotation.AnnotationConfigApplicationContext;
import com.springboot.chapter3.pojo.User;

public class IocTest{

  private static Logger log = Logger.getLogger(IocTest.class);

  public static void main(String[] args){

    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

    User user = ctx.getBean(User.class);

    log.info(user.getId);

  }

}

代码中将Java 配置文件AppConfig 传递给AnnotationConfigApplicationContext 的构造方法,这
样它就能够读取配置了。然后将配置里面的Bean 装配到IoC 容器中,于是可以使用getBean 方法获
取对应的POJO

通过扫描装配你的Bean

如果一个个的Bean 使用注解@Bean 注入Spring loC 容器中,那将是一件很麻烦的事情。好在
Spring 还允许我们进行扫描装配Bean 到loC 容器中,对于扫描装配而言使用的注解是@Component
和@ComponentScan 。@Component 是标明l哪个类被扫描进入Spring IoC 容器,而@ComponentScan
则是标明采用何种策略去扫描装配Bean

package com.springboot.chapter3.config ;
@Component (”user")
public class User {
@Value (” 1 ”)
private Long id;
@Value (”user name 1”}
private String userName ;
@Value (”note 1”)
private String note;
/**setter and getter **/

}

这里的注解@Component 表明这个类将被Spring IoC 容器扫描装配,其中配置的“ user "则是作为
Bean 的名称,当然你也可以不配置这个字符串,那么IoC 容器就会把类名第一个字母作为小写,其他
不变作为Bean 名称放入到IoC 容器中;注解@Value 则是指定具体的值,使得Spring IoC 给予对应的
属性注入对应的值。为了让Spring IoC 容器装配这个类, 需要改造类AppConfig ,

package com.springboot.chapter3.config ;
import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotationConfiguration;
@Configuration
@ComponentScan
public class AppConfig {
}

这里加入了@ComponentScan ,意味着它会进行扫描,但是它只会扫描类AppConfig 所在的当前
包和其子包。

为了更加合理,@ ComponentScan 还允许我们自定义扫描的包.

@ComponentScan (”com.springboot.chapter3.* ” )

@ComponentScan(basePackages = {”com.springboot.chapter3.pojo” })

ComponentScan(basePackageClasses = {User.class} )

无论采用何种方式都能够使得IoC 容器去扫描User 类,而包名可以采用正则式去匹配。但是有
时候我们的需求是想扫描一些包,将一些Bean 装配到Spring IoC 容器中,而不是想加载这个包里面
的某些Bean 。

ComponentScan(basePackages = "com.springboot.chapter3.*”,
excludeFilters = {@Filter(classes = {Service.class})})

这样,由于加入了excludeFilters 的配置,使标注了@Service 的类将不被IoC 容器扫描注入,这
样就可以把UserService 类排除到Spring IoC 容器中了

现实的Java 的应用往往需要引入许多来自第三方的包, 并且很有可能希望把第三方包的类对象
也放入到Spring IoC 容器中,这时@Bean 注解就可以发挥作用了。

例如, 要引入一个DBCP 数据源,我们先在pom.xml 上加入项目所需要DBCP 包和数据库MySQL
驱动程序的依赖

<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-dbcp2</artifactid>
</dependency>
<dependency>
<groupid>mysql</groupid>
<artifactid>mysql-connector- java</artifactid>
</dependency>
这样DBCP 和数据库驱动就被加入到了项目中,接着将使用它提供的机制来生成数据源。

@Bean(name = "dataSource")
public DataSource getDataSource () {
Properties props= new Properties();

props.setProperty(”driver ”,”com.mysql . jdbc.Driver ");
props.setProperty("url”,”jdbc:mysql://localhost:3306/chapter3”);
props.setProperty(”username”,”root") ;
props.setProperty(”password ”,”123456”) ;
DataSource dataSource = null ;
try {
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch ( Exception e) {
e. printStackTrace ();
return dataSource;

}

这里通过@Bean 定义了其配置项name 为“ dataSource 飞那么Spring 就会把它返回的对象用名
称“ dataSource ” 保存在loC 容器中。当然, 你也可以不填写这个名称,那么它就会用你的方法名称
作为Bean 名称保存到roe 容器中。通过这样,就可以将第三方包的类装配到Spr ing IoC 容器中了。

猜你喜欢

转载自blog.csdn.net/weixin_42218986/article/details/87177697