Spring第七篇_Spring的新注解

15 篇文章 0 订阅

准备工作:

​ 1. 创建工程 day02_eesy_04account_annoioc_withoutxml

​ 2. 在pom.xml文件中完成相关配置

​ 3. 将工程day02_eesy_04account_annoioc的相关文件全部都复制到该工程对应目录下,

​ 4. 即工程 day02_eesy_04account_annoioc_withoutxml的初始状态和工程day02_eesy_04account_annoioc的

​ 完结状态相同

​ 5. 创建配置类SpringConfiguration.java

1. ComponentScan

1.1 介绍

Configuration
作用: 指定当前类是一个配置类

1.2 案例

在配置类SpringConfiguration.java进行@Configuration注解配置

/**
 * 该类是一个配置类, 他的作用和bean.xml是一样的
 * spring中的新注解
 * Configuration
 *      作用: 指定当前类是一个配置类
 */
@Configuration
public class SpringConfiguration {

 
}

2. ComponentScan

2.1 介绍

作用: 用于通过注解指定Spring在创建容器时要扫描的包
属性:
value: 他和basePackages的作用是一样的, 都是用于指定创建容器时要扫描的包
我们使用此注解就相当于在xml中配置了:

<context:component-scan base-package="com.itheima"></context:component-scan>
2.2 案例

在配置类SpringConfiguration.java进行@ ComponentScan注解配置

/**
 * 该类是一个配置类, 他的作用和bean.xml是一样的
 * spring中的新注解
 * Configuration
 *      作用: 指定当前类是一个配置类
 * ComponentScan
 *      作用: 用于通过注解指定Spring在创建容器时要扫描的包
 *      属性:
 *          value: 他和basePackages的作用是一样的, 都是用于指定创建容器时要扫描的包
 *                  我们使用此注解就相当于在xml中配置了:
 *                      <context:component-scan base-package="com.itheima"></context:component-scan>
 */
@Configuration
@ComponentScan(basePackages = {"com.itheima"})  //或@ComponentScan(basePackages = "com.itheima")或@ComponentScan("com.itheima")
public class SpringConfiguration {
}

3. Bean

3.1 介绍

Bean
作用: 用于把当前方法的返回值作为bean对象存入spring的ioc容器中
属性:
name: 用于指定bean的id; 当不写时,默认值是当前方法的名称
细节:
当我们使用注解配置方法时, 如果方法有参数, spring框架就会去容器中查找有没有可用的bean对象;
查找的方式和Autowired注解的方式是一样的

3.2 案例

在配置类SpringConfiguration.java进行@ Bean注解配置

/**
 * 该类是一个配置类, 他的作用和bean.xml是一样的
 * spring中的新注解
 * Configuration
 *      作用: 指定当前类是一个配置类
 * ComponentScan
 *      作用: 用于通过注解指定Spring在创建容器时要扫描的包
 *      属性:
 *          value: 他和basePackages的作用是一样的, 都是用于指定创建容器时要扫描的包
 *                  我们使用此注解就相当于在xml中配置了:
 *                      <context:component-scan base-package="com.itheima"></context:component-scan>
 * Bean
 *      作用: 用于把当前方法的返回值作为bean对象存入spring的ioc容器中
 *      属性:
 *          name: 用于指定bean的id; 当不写时,默认值是当前方法的名称
 *      细节:
 *          当我们使用注解配置方法时, 如果方法有参数, spring框架就会去容器中查找有没有可用的bean对象;
 *          查找的方式和Autowired注解的方式是一样的
 */
@Configuration
@ComponentScan(basePackages = {"com.itheima"})  //或@ComponentScan(basePackages = "com.itheima")或@ComponentScan("com.itheima")
public class SpringConfiguration {

    /**
     * 用于创建一个QueryRunner对象
     */
    @Bean(name = "runner")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     */
    @Bean("datasource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass("");

            dataSource.setJdbcUrl("");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

说明: 这一段使用bean注解的代码与bean.xml文件中的

<!--配置QueryRunner-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <!--QueryRunner的默认作用范围是单例的,为了避免线程之间的相互影响,将其设置为多例的-->
        <!--注入数据源-->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <!--配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--连接数据库的必备信息-->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

相对应

4. 使用 AnnotationConfigApplicationContext(.class)获取容器

为了将bean.xml配置文件删除也能获取到IOC容器, 获取容器的方式改为

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);

括号中为配置类的字节码

完善AccountServiceTest.java如下:

**
 * 使用Junit单元,测试我们的配置
 */
public class AccountServiceTest {

    private ApplicationContext applicationContext;

    private IAccountService accountService;

    @Before
    public void init(){
//        1. 获取容器

        //通过解析注解配置类得到applicationContext
       applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
//        2. 得到业务层对象
        accountService=applicationContext.getBean("accountService",IAccountService.class);


    }


    @Test
    public void testFindAll(){
//        3. 执行方法
        List<Account> accounts = accountService.findAllAccount();

        for(Account account:accounts){
            System.out.println(account);
        }

    }

    @Test
    public void testFindById(){

//        3. 执行方法
        Account account=accountService.findAccountById(1);
        System.out.println(account);
    }

    @Test
    public void testSave(){
//        3. 执行方法
        Account account = new Account();
        account.setName("test");
        account.setMoney(12345.0);
        accountService.saveAccount(account);

    }

    @Test
    public void testUpdate(){
//        3. 执行方法
        Account account = accountService.findAccountById(5);
        account.setMoney(1234.0);
        accountService.updateAccount(account);
    }

    @Test
    public void testDelete(){

        accountService.deleteAccount(4);
    }
}

5. 修改QueryRunner作用范围

5.1 为返回QueryRunner的方法添加注解@Scope

SpringConfiguration.java

@Configuration
@ComponentScan(basePackages = {"com.itheima"})  //或@ComponentScan(basePackages = "com.itheima")或@ComponentScan("com.itheima")
public class SpringConfiguration {

    /**
     * 用于创建一个QueryRunner对象
     */
    @Bean(name = "runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     */
    @Bean("datasource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass("com.mysql.jdbc.Driver");

            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/eesy");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

5.2 创建测试类TestQueryRunner.java
/**
 * 测试QueryRunner是否单例
 */
public class QueryRunnerTest {


    @Test
    public void testQueryRunner() {

        //1. 获取容器
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);

        //2. 获取QueryRunner对象
        QueryRunner runner = applicationContext.getBean("runner",QueryRunner.class);
        QueryRunner runner2 = applicationContext.getBean("runner",QueryRunner.class);

        System.out.println(runner == runner2);

    }

}

6. Import

用于解决配置类的导入问题

6.1 新建一个配置类JdbcConfig.java用于进行数据库方面的配置
/**
 * 和Spring连接数据库相关的配置
 */

public class JdbcConfig {

    /**
     * 用于创建一个QueryRunner对象
     */
    @Bean(name = "runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }


    /**
     * 创建数据源对象
     * @return
     */
    @Bean("datasource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass("com.mysql.jdbc.Driver");

            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/eesy");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

6.2 在主配置文件SpringConfiguration.java中导入该配置类
/**
 * 该类是一个配置类, 他的作用和bean.xml是一样的
 * spring中的新注解
 * Configuration
 *      作用: 指定当前类是一个配置类
 *      细节: 当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写
 * ComponentScan
 *      作用: 用于通过注解指定Spring在创建容器时要扫描的包
 *      属性:
 *          value: 他和basePackages的作用是一样的, 都是用于指定创建容器时要扫描的包
 *                  我们使用此注解就相当于在xml中配置了:
 *                      <context:component-scan base-package="com.itheima"></context:component-scan>
 *
 * Bean
 *      作用: 用于把当前方法的返回值作为bean对象存入spring的ioc容器中
 *      属性:
 *          name: 用于指定bean的id; 当不写时,默认值是当前方法的名称
 *      细节:
 *          当我们使用注解配置方法时, 如果方法有参数, spring框架就会去容器中查找有没有可用的bean对象;
 *          查找的方式和Autowired注解的方式是一样的
 *
 * Import:
 *      作用: 用于导入其他配置类
 *      属性:
 *          value: 用于指定其他配置类的字节码
 *                  当我们使用Import的注解之后, 有Import注解的类就是夫配置类, 而导入的都是子配置类
 */
@Configuration
@ComponentScan(basePackages = {"com.itheima"})  //或@ComponentScan(basePackages = "com.itheima")或@ComponentScan("com.itheima")
@Import(JdbcConfig.class)
public class SpringConfiguration {

}

说明: 当配置类作为AnnotationConfigApplicationContext对象创建的参数时,@Configuration注解可以不写

7. PropertySource

用于读取配置文件 jdbc.properties 的数据

7.1 创建jdbc.properties

jdbc.properties用于存放数据库相关的数据

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=123456
7.2 修改JdbcConfig.java类
**
 * 和Spring连接数据库相关的配置
 */

public class JdbcConfig {

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

    /**
     * 用于创建一个QueryRunner对象
     */
    @Bean(name = "runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }


    /**
     * 创建数据源对象
     * @return
     */
    @Bean("datasource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass(driver);

            dataSource.setJdbcUrl(url);
            dataSource.setUser(username);
            dataSource.setPassword(password);
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

7.3 为主配置文件 SpringConfiguration.java添加ProprttySource注解
 *
 * Import:
 *      作用: 用于导入其他配置类
 *      属性:
 *          value: 用于指定其他配置类的字节码
 *                  当我们使用Import的注解之后, 有Import注解的类就是夫配置类, 而导入的都是子配置类
 * PropertySource:
 *      作用: 用于指定properties文件的位置
 *      属性:
 *          value: 指定文件的名称和路径
 *                  关键字: classpath, 表示类路径下
 *
 */
@Configuration
@ComponentScan(basePackages = {"com.itheima"})  //或@ComponentScan(basePackages = "com.itheima")或@ComponentScan("com.itheima")
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {



}

8. 总结

如果是自己创建的类, 用注解方式比较简单

如果是jar包中封装的对象,直接在xml文件中配置比较简单

9. Qualifier

Qualifier一方面可以和Autwired联合使用

​ 另一方面可以指定方法中形式参数的注入id

9.1 创建数据库eesy02
create eesy02;
9.2 创建数据库表 account
create table account(
	id int primary key auto_increment,
	name varchar(40),
	money float
)character set utf8 collate utf8_general_ci;

insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);

9.3 修改JdbcConfig.java
/**
 * 和Spring连接数据库相关的配置
 */

public class JdbcConfig {

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

    /**
     * 用于创建一个QueryRunner对象
     */
    @Bean(name = "runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(@Qualifier("datasource2") DataSource dataSource){
        return new QueryRunner(dataSource);
    }


    /**
     * 创建数据源对象
     * @return
     */
    @Bean("datasource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass(driver);

            dataSource.setJdbcUrl(url);
            dataSource.setUser(username);
            dataSource.setPassword(password);
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    @Bean("datasource2")
    public DataSource createDataSource2() {
        try {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();

            dataSource.setDriverClass("com.jdbc.driver");

            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/eesy02");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            return dataSource;

        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

此时Spring的IOC容器中有两个DataSource类型的对象, Qualifier的作用就是指定注入的是哪一个DataSource

9.4 在AccountServiceTest.java中运行

运行结果:

3. Spring整合junit

3.1 问题分析
  1. 程序的入口

    ​ main方法

  2. junit单元测试中,没有main方法也能执行

    ​ junit集成了一个main方法

    ​ 该方法就会判断当前测试类中哪些方法有 @Test 注解

    ​ junit就会让有 @Test 注解的方法执行

  3. junit不会管我们是否采用Spring框架

    ​ 在执行测试方法时, junit根本不知道我们是不是使用了Spring框架

    ​ 所以也就不会为我们读取配置文件/配置类创建Spring容器

  4. 由以上三点可知

    ​ 当测试方法执行时,没有IOC容器,即使写了 Autowired 注解,也无法实现注入

3.2 整合步骤

在测试类AccountServiceTest.java中完成整合

/**
 * 使用Junit单元,测试我们的配置
 * Spring整合junit的配置
 *      1.导入Spring整合junit的jar包(坐标)
 *      2. 使用Junit提供的注解 @Runwith 把原有的main方法替换掉, 替换成Spring提供的
 *              @Runwith
 *      3. 告知Spring的运行器,Spring和IOC创建是基于xml还是注解, 并且说明位置
 *          @ContextConfiguration
 *                  locations: 指定xml文件的位置,加上classpath关键字,表示在类路径下
 *                  classes:   指定注解类所在位置
 *
 *      细节: 当我们使用Spring 5.x 版本的时候,要求junit的jar包必须是 4.12版本及以上
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class AccountServiceTest {


    @Autowired
    private IAccountService accountService=null;

    @Test
    public void testFindAll(){
//        3. 执行方法
        List<Account> accounts = accountService.findAllAccount();

        for(Account account:accounts){
            System.out.println(account);
        }

    }

    @Test
    public void testFindById(){

//        3. 执行方法
        Account account=accountService.findAccountById(1);
        System.out.println(account);
    }

    @Test
    public void testSave(){
//        3. 执行方法
        Account account = new Account();
        account.setName("test");
        account.setMoney(12345.0);
        accountService.saveAccount(account);

    }

    @Test
    public void testUpdate(){
//        3. 执行方法
        Account account = accountService.findAccountById(5);
        account.setMoney(1234.0);
        accountService.updateAccount(account);
    }

    @Test
    public void testDelete(){

        accountService.deleteAccount(4);
    }
}

在pom.xml中添加的依赖为:

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.4.RELEASE</version>
  </dependency>

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值