一、案例:使用 spring 的 IoC 的实现账户的 CRUD
1.1 需求和技术要求:
1.1.1 需求:实现账户的 CRUD 操作
1.1.2 技术要求:
使用 spring 的 IoC 实现对象的管理
使用 DBAssit 作为持久层解决方案
使用 c3p0 数据源
1.2 环境搭建
1.2.1 拷贝 jar 包:
1.2.2 创建数据库和编写实体类:
1.2.3 编写持久层代码:
1.2.4 编写业务层代码:
1.2.5 创建并编写配置文件约束:
1.3 配置步骤:
1.4 测试案例
1.4.1 测试类代码
1.4.2 分析测试中出现的问题:通过上面的测试类,我们可以看出,每个测试方法都重新获取了一次 spring 的核心容器,造成了不必要的重复代码,增加了我们开发的工作量。这种情况,在开发中应该避免发生。
二、基于注解的 IOC 配置
2.1 写在前面: 学习基于注解的 IoC 配置,要明确一个概念,即注解配置和xml配置要实现的功能都是一样的,都是要降低程序间的耦合,只是配置的形式不一样。关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌握。
2.2 环境搭建
2.2.1 第一步:拷贝必备 jar 包到工程的 lib 目录,在基于注解的配置中,我们还要多拷贝一个 aop 的 jar 包。
2.2.2 第二步:使用@Component 注解配置管理的资源
2.2.3 第三步:创建 spring 的 xml 配置文件并开启对注解的支持
2.3 常用注解:
2.3.1 用于创建对象的:
2.3.1.1 @Component
作用:把资源让 spring 来管理,相当于在 xml 中配置一个 bean。
属性:
value:指定 bean 的 id,如果不指定 value 属性,
默认 bean 的 id 是当前类的类名,首字母小写。
2.3.1.2 @Controller @Service @Repository
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。
细节:如果注解中有且只有一个属性要赋值时,
且名称是 value,那么value 在赋值时可以不写。
2.3.2 用于注入数据的:
2.3.2.1 @Autowired
作用: 自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。
2.3.2.2 @Qualifier
作用: 在自动按照类型注入的基础之上,再按照 Bean的id 注入。
它在给字段注入时不能独立使用,必须和@Autowire 一起使用;
但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。
2.3.2.3 @Resource
作用: 直接按照 Bean 的 id 注入,它也只能注入其他 bean 类型。
属性:
name:指定 bean 的 id。
2.3.2.4 @Value
作用: 注入基本数据类型和 String 类型数据
属性:
value:用于指定值
2.3.3 用于改变作用范围的:
2.3.3.1 @Scope
作用: 指定 bean 的作用范围。
属性:
value:指定范围的值。
取值:singleton prototype request session globalsession
2.3.4 和生命周期相关的:
2.3.4.1 @PostConstruct
作用: 用于指定初始化方法。
2.3.4.2 @PreDestroy
作用: 用于指定销毁方法。
2.3.5 关于 Spring 注解和 XML 的选择问题:
注解的优势: 配置简单,维护方便(我们找到类,就相当于找到了对应的配置)
XML 的优势: 修改时,不用改源码。不涉及重新编译和部署。
Spring 管理 Bean 方式的比较:
2.4 新注解说明:
2.4.1 @Configuration
作用: 用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用 AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性: value:用于指定配置类的字节码
2.4.2 @ComponentScan
作用: 用于指定 spring 在初始化容器时要扫描的包。作用和在spring的xml 配置文件中的 <context:component-scan base-package="com.itheima" />是一样的。
属性:
basePackages:用于指定要扫描的包
2.4.3 @Bean
作用: 该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring容器。
属性:
name:给当前@Bean注解方法创建的bean对象指定一个id
2.4.4 @PropertySource
作用:用于加载.properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。
属性: value[]:用于指定 properties 文件位置。
如果是在类路径下,需要写上 classpath:
2.4.5 @Import
作用: 用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。
属性:
value[]:用于指定其他配置类的字节码。
2.4.6 通过注解获取容器:
三、Spring 整合 Junit
3.1 测试类中的问题和解决思路
3.1.1 问题:在测试类中,每个测试方法都有以下两行代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); IAccountService as = ac.getBean("accountService",IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
3.1.2 解决思路分析:针对上述问题,我们需要的是程序能自动帮我们创建容器。一旦程序能自动为我们创建 spring 容器,我们就无须手动创建了,问题也就解决了。junit 给我们暴露 了一个注解,可以让我们替换掉它的运行器。 这时,我们需要依靠 spring 框架,因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我们只需要告诉它配置文件在哪就行了。
3.2配置步骤
3.2.1 第一步:拷贝整合 junit 的必备 jar 包到 lib 目录
3.2.2 第二步:使用@RunWith 注解替换原有运行器:
3.2.3 第三步:使用@ContextConfiguration 指定 spring 配置文件的位置
@ContextConfiguration 注解:
locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。
3.2.4 第四步:使用@Autowired 给测试类中的变量注入数据
3.3 为什么不把测试类配到 xml 中?
在解释这个问题之前,先明确一点,把测试类配置到xml中是可以正常使用的, 那么为什么不采用配置到 xml 中的方式呢? 这个原因是这样的:
第一:当我们在 xml 中配置了一个 bean,spring 加载配置文件创建容器时,就会创建对象。
第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。
所以,基于以上两点,我们不应该把测试配置到 xml 文件中
网友评论