Spring框架 _ IOC/DI、核心容器、注解开发


Spring框架 _ IOC/DI、核心容器、注解开发

一、IOC/DI配置管理第三方bean

1.1 案例 _ 数据源对象管理

1.1.1 第三方资源配置管理

导入druid坐标

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

配置数据源对象作为spring管理的bean

<!--    管理DruidDataSource对象-->
   <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

1.2 加载properties文件

1.2.1 加载properties配置信息

(1)开启context命名空间

<?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
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            ">
</beans>

(2)使用context命名空间,加载指定properties文件

<!--    1.开启context命名空间-->
<!--    2.使用context空间加载properties文件-->
    <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
    <context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>

(3)使用${}读取加载的属性值

<!--    3.使用属性占位符${}读取properties文件中的属性-->
<!--    说明:idea自动识别${}加载的属性值,需要手工点击才可以查阅原始书写格式-->
    <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

(4)其他

二、核心容器

2.1 创建容器

public class App {
    public static void main(String[] args) {
    
        //1.加载类路径下的配置文件、ClassPathXmlApplicationContext[掌握]
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        
        //2.从文件系统下加载配置文件、FileSystemXmlApplicationContext[知道即可]
        ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
        BookDao bookDao = ctx.getBean(BookDao.class);
        bookDao.save();
        
        //3.加载多个配置文件(了解下即可)
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");
    }
}

2.2 获取bean

        //1.使用bean名称获取 (getBean("名称"):需要类型转换)
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        
       //2.使用bean名称获取指定类型 (getBean("名称",类型.class):多了一个参数)
        BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
        
        //3.使用bean类型获取 (getBean(类型.class):容器中不能有多个该类的bean对象)
        BookDao bookDao = ctx.getBean(BookDao.class);
        
        bookDao.save();

2.3 容器类层次结构

  • 只需要知晓容器的最上级的父接口为 BeanFactory即可

2.4 BeanFactory

  • 使用BeanFactory创建的容器是延迟加载;
  • 使用ApplicationContext创建的容器是立即加载;
  • 具体BeanFactory如何创建只需要了解即可。

2.5 核心容器-总结

2.5.1 容器相关

  • BeanFactory是Ioc容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
  • ApplicationContext接口常用初始化类

    • classPathXmlApplicationContext
    • FileSystemXmlApplicationContext

2.5.2 bean相关

  • 其实整个配置中最常用的就两个属性id和class。
  • scope、init-method、destroy-method在后面注解在讲解的时候还会用到, 所以对这三个属性关注下。

2.5.3 依赖注入相关

(1)构造器注入

  • 一般用在第三方技术整合

(2)setter注入

  • 对于我们自己写的类,这种方式用的相对比较多

三、IOC/DI注解开发

3.1 注解开发定义bean

3.1.1 使用@Component定义bean

  • 注意:@Component注解不可以添加在接口上,因为接口是无法创建对象的。
@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}

3.1.2 核心配置文件中通过组件扫描加载bean

        <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

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

</beans>

3.1.3 说明

3.1.4 Spring提供@Component注解的三个衍生注解

3.2 纯注解开发

  • Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道

3.2.1 Java类代替Spring核心配置文件

3.2.2 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象

3.3 bean作用范围

3.3.1 @scope

(1)使用@Scope定义bean作用范围

@Repository
//@Scope设置bean的作用范围
@Scope("singleton")
public class BookDaoImpl implements BookDao {

}

3.4 bean生命周期

3.4.1 @PostConstruct、@PreDestroy

(1)使用@PostConstruct、@PreDestroy定义bean生命周期

@Repository
//@Scope设置bean的作用范围
@Scope("singleton")
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("book dao save ...");
    }
    //@PostConstruct设置bean的初始化方法 (在构造方法之后执行,替换 init-method)
    @PostConstruct
    public void init() {
        System.out.println("init ...");
    }
    
    
    //@PreDestroy设置bean的销毁方法  (在销毁方法之前执行,替换 destroy-method)
    @PreDestroy
    public void destroy() {
        System.out.println("destroy ...");
    }

}

(2)注意

  • @PostConstruct和@PreDestroy注解如果找不到,需要导入下面的jar包
  • 找不到的原因是,从JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中。
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>

3.5 注解开发依赖注入

3.5.1 自动装配

  • Spring为了使用注解简化开发,并没有提供构造函数注入、setter注入对应的注解,只提供了自动装配的注解实现。

(1)@Autowired

使用@Autowired注解开启自动装配模式(按类型)

  • 注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。
  • 注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法。
实例
@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    //@Qualifier:自动装配bean时按bean名称装配
    @Qualifier("bookDao")
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

(2)@Qualifier

使用@Qualifier注解开启指定名称装配bean

  • 注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用
实例
@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    //@Qualifier:自动装配bean时按bean名称装配
    @Qualifier("bookDao")
    private BookDao bookDao;

}

(3)@value

使用@Value实现简单类型注入

@Repository("bookDao")
public class BookServiceImpl2 implements BookService {
    @Value("test")
    private String name;


    public void save() {
        System.out.println("book service save ..." + name) ;
    }
}

3.5.2 注解读取properties配置文件

@PropertySource

3.5.3 总结-知识点

四、IOC/DI注解开发管理第三方bean

4.1 注解开发管理第三方bean

4.1.1 @Bean

  • 完成对Druid数据源的管理。

(1)导入对应的jar包

  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
  </dependency>
</dependencies>

(2)在配置类中添加一个方法 - 在方法上添加@Bean注解

  • 注意该方法的返回值就是要创建的Bean对象类型。
  • @Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象。
  • 注意:不能使用DataSource ds = new DruidDataSource()
  • 因为DataSource接口中没有对应的setter方法来设置属性。
@Configuration
public class SpringConfig {

    //1.定义一个方法获得要管理的对象
    //2.添加@Bean,表示当前方法的返回值是一个bean
    //@Bean修饰的方法,形参根据类型自动装配
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

(3)从IOC容器中获取对象并打印

  • 如果有多个bean要被Spring管理,直接在配置类中多些几个方法,方法上添加@Bean注解即可。
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = ctx.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

4.2 引入外部配置类

4.2.1 使用包扫描引入(不推荐使用)

  • 有兴趣可以看文档。(这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,所有这种方式不推荐使用)

4.2.2 使用@Import引入

  • 可以不用加@Configuration注解,但是必须在Spring配置类上使用@Import注解手动引入需要加载的配置类。

(1)去除JdbcConfig类上的注解

public class JdbcConfig {
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

(2)在Spring配置类中引入

@Configuration
@ComponentScan("com.li")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}

(3)注意

  • 扫描注解可以移除
  • @Import参数需要的是一个数组,可以引入多个配置类。
  • @Import注解在配置类中只能写一次,下面的方式是不允许的

4.3 知识点(@Bean---@Import)

4.4 注解开发实现为第三方bean注入资源

  • 在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?
  • 这些资源会有两大类,分别是简单数据类型引用数据类型
  • 第三方bean依赖注入 —— ①引用类型:方法形参
  • ​ ②简单类型:成员变量

4.4.1 简单数据类型

(1)类中提供四个属性 - 使用@Value注解引入值

//@Configuration
public class JdbcConfig {
    //1.定义一个方法获得要管理的对象
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String userName;
    @Value("root")
    private String password;
    //2.添加@Bean,表示当前方法的返回值是一个bean
    //@Bean修饰的方法,形参根据类型自动装配
    @Bean
    public DataSource dataSource(BookDao bookDao){
        System.out.println(bookDao);
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

(2)扩展

4.4.2 引用数据类型

  • 假设在构建DataSource对象的时候,需要用到BookDao对象,该如何把BookDao对象注入进方法内,让其使用呢?

(1)在SpringConfig中扫描BookDao

  • 扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象
@Configuration
@ComponentScan("com.itheima")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}

(2)在JdbcConfig类的方法上添加参数

    @Bean
    public DataSource dataSource(BookDao bookDao){
        System.out.println(bookDao);
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

(3)总结

  • 引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象。

五、注解开发总结

5.1 XML配置与注解配置比较

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Spring框架 _ IOC/DI、核心容器、注解开发


三二一的一的二