【ssm入门#6-Spring5】注解方式实现IOC:注解XML交叉运用+纯注解+整合junit测试

本文基于下述教程编写:【B站】ssm教程

注解XML交叉运用


@Component
他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。 他们只不过是提供了更加明确的语义化。
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。

@Autowired
作用:
自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型(非基本类型及String)。当有多个类型匹配时,使用要注入的对象变量名称作为 beanid,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

@Component
public class AccountServiceImpl implements IAccountService {
    //自动注入
    @Autowired
    private IAccountDao accountDao1;
    }

在这里插入图片描述
上图需要注入的成员变量名称是accountDao,虽然有两个实现类Bean与之对应,但是进行第二步查找时名称不对应,会查找失败。
@Qualifier:在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowire 一起使用;但是给方法参数注入时,可以独立使用。

@Component
public class AccountServiceImpl implements IAccountService {
    @Autowired
    @Qualifier("accountDao1")//名称不一,但可以指定对应的bean
    private IAccountDao accountDao;

@Resource
直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。

无论是@Autowired还是@Resource都无法实现基本数据类型String的数据注入,并且集合这样复杂的数据类型只能通过XML配置注入,注解方式无能为力。

@PostConstruct
用于指定Bean初始化方法
@PreDestroy
用于指定Bean销毁方法,注意多例模式只能被java回收,不能主动销毁。

在注解方式实现容器下,bean.xml要用有别于XML实现的约束:

<?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">
    <!--把对象的创建交给Spring管理-->

    <!--扫描需要反射的Bean的目录-->
   <context:component-scan base-package="com.spring5Annotation"> </context:component-scan>
</beans>

但是有一个问题,这并没有和XML方式配置有根本上的差别,还是基于bean.xml存在。经过写配置类彻底变成纯注解配置。

纯注解

@Configuration
@ComponentScan("com.littleinstance")//扫描包下的字节码文件,不然提示找不到Bean
public class SpringConfiguration {

    @Bean(name = "runner")//默认单例
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    @Bean(name = "dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setUser("root");
            ds.setPassword("root");
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/ssmTest");
            return ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

DateSourceQueryRunner的成员属性,QueryRunnerAccountDao的成员属性,AccountDaoAccountService的成员属性。通过xml配置是分别配置不同的<bean>标签,用<property>标签的ref属性指定实现依赖的。

而在配置类中需要写创造Bean的方法并用@Bean标记从而放进Spring容器里面的,只要放进了容器,会自动寻找合适的对象自动完成匹配。注意QueryRunner要指定为多例模式,否则危及线程安全。此时bean.xml不再需要,但是要再测试类完成文件引用的修改:

//基于XML配置
        //ac=new ClassPathXmlApplicationContext("bean1.xml");

        //基于注解配置
        ac=new AnnotationConfigApplicationContext(SpringConfiguration.class);

但是,Spring如何匹配DataSource对象到QueryRunner里面的呢?万一QueryRunner有两个DataSource呢?怎么完成一一对应?
在这里插入图片描述
是的,当有多个同类型的对象就回到一开始讨论的情况,匹配对应的方法也是和XML配置方法一样的,此时@Qualifier注解就可以在参数的旁边标注具体使用哪个Bean作为QueryRunner的参数。另外,将参数名改成BeanID,不使用@Qualifier也可以实现,不过就不符合命名的自由规范了。

@ComponentScan
扫描包下的字节码文件,不然提示找不到Bean,相当:

<!--扫描需要反射的Bean的目录-->
   <context:component-scan base-package="com.spring5Annotation"> </context:component-scan>

细节:当如上方式加载目标类字节码文件时,@Configuration可以省略,但是当需要用到的配置类不当字节码文件传入时,一定要被指定扫描并且标记@Configuration,否则找不到Bean

然而人懒起来真的可怕,当你不想标注@Configuration,也不想引入字节码文件时,还希望多个配置文件可以有个明确的父子关系,下面这个标签应运而生。

@Import
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问题。 尽管如此,@ComponentScan还是不能省略。
在这里插入图片描述
@PropertySource
用于加载.properties文件中的配置,参数value[]:用于指定 properties 文件位置,可传入多个或单个路径,单个可以省略"value="大括号。如果是在类路径下,需要写上 classpath:
在这里插入图片描述

整合junit测试


为什么Spring要整合junit?
我们追求各个框架能够充分合作,并且能写少一行代码绝对不想写多一行。

Spring要整合junit,怎么理解
当我们不整合时,每次测试类代码中就会获取资源文件手动创建一次Spring容器:
在这里插入图片描述
但是,Junit并不能预测到我们用啥子框架,他并不知道Spring的存在,所以进行整合就要换掉Junit原始运行器。好在Junit也不小家子脾气,大度地为我们提供了注解@RunWith让我们根据需求自己手动换成自己所需的运行器。Spring当然也不小气,为了方便我们整合测试类,提供了一个叫SpringJUnit4ClassRunner的类,该类只需要你提供创建Spring容器的配置文件/配置类,就可以自动为我们创建容器,一行代码都不用写。

Spring整合junit步骤
1.拿到Spring专门为我们提供的整合测试类运行器:

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

当然Junit也少不了,但是要明确版本要求大于等于4.12(Spring5.0以上要求),不然报错:

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
</dependency>

2.告诉Junit我们嫌弃你了,换成Spring的运行器:

@RunWith(SpringJUnit4ClassRunner.class)

3.告知Spring你在用什么配置容器,XML方式就给出bean.xml文件,注解方式就给出配置类字节码文件。

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration( classes = SpringConfiguration.class)  //注解方式用classes
@ContextConfiguration( locations = "classpath:bean.xml")	//xml方式用location,别忘了classpath:

4.依赖注入,配置成员变量。来到这里,IAccountService 被自动依赖注入,其实在Spring容器里IAccount的匹配过程也如文首提到的流程走了一遍。在整合测试类中少写了读取配置的代码,不用ApplicationContextgetBean()方法得到实例对象。

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration( classes = SpringConfiguration.class)
@ContextConfiguration( locations = "classpath:bean.xml")
public class AccountServiceTest {

    @Autowired
    IAccountService as;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值