【SpringFramework】Spring⼊门教程(三)使⽤注解配置
本⽂主要介绍四个⽅⾯:
(1) 注解版本IOC和DI
(2) Spring纯注解
(3) Spring测试
(4) SpringJDBC - Spring对数据库的操作
使⽤注解配置Spring⼊门
说在前⾯
学习基于注解的IoC配置,⼤家脑海⾥⾸先得有⼀个认知,即注解配置和xml配置要实现的功能都是⼀样的,都是要降低模块间的耦合度。仅仅只是配置的形式不⼀样。关于实际的开发中到底使⽤xml还是注解,每家公司有着不同的使⽤习惯。所以这两种配置⽅式我们都需要掌握。
基于注解配置的⽅式也已经逐渐代替xml配置。所以我们必须要掌握使⽤注解的⽅式配置Spring。
配置步骤
注意:如果使⽤Eclipse需要先安装了STS插件,或者使⽤STS开发⼯具创建项⽬。本⽂使⽤IDEA进⾏演⽰。
1.2.1. 第⼀步:拷贝必备jar包到⼯程的lib⽬录。
注意:在基于注解的配置中,我们还要多拷贝⼀个aop的jar包。如下图:
1.2.2. 第⼆步:在类的根路径下创建⼀个任意名称的xml⽂件(不能是中⽂)
注意:基于注解整合时,Spring配置⽂件导⼊约束时需要多导⼊⼀个context命名空间下的约束。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="/schema/beans
/schema/beans/spring-beans.xsd
/schema/context
/schema/context/spring-context.xsd">
</beans>
1.2.3. 第⼆步:创建⼀个服务类
创建⼀个测试的服务类,并且加⼊使⽤@Component注解,声明该类允许注⼊到Spring容器
package org.cjw.service;
import org.springframework.stereotype.Component;
/*
使⽤注解配置时,需要将Spring框架启动就创建对象的类表⽰为组件类
表⽰组件类使⽤@Component注解
*/
@Component
public class CustomerService {
public void save() {
System.out.println("-保存数据-");
}
}
1.2.4. 第四步在spring的配置⽂件加⼊扫描注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="/schema/beans
/schema/beans/spring-beans.xsd
/schema/context
/schema/context/spring-context.xsd">
<!-- 声明扫描包及其⼦包的类,如果发现有组件注解的类,就创建对象并加⼊到容器中去 -->
<context:component-scan base-package="org.cjw" />
</beans>
1.2.5. 第五步:测试调⽤代码
package st;
import org.cjw.service.CustomerService;
import org.junit.Test;
import t.ApplicationContext;
import t.support.ClassPathXmlApplicationContext;
public class CustomerServiceTest {
@Test
public void testSave() {
ApplicationContext context = new ClassPathXmlApplicationContext("l");
CustomerService customerService = Bean(CustomerService.class);
customerService.save();
}
}
--测试结果,如果可以调⽤服务⽅法,测试成功。
1.2.6. 设置注解扫描的组件的名称
默认情况下,被注解@Component 扫描的类的名称就是当前类名的⾸字母⼩写名称,开发者可以⾃定义组件的名称。
--组件类
package org.cjw.service;
import org.springframework.stereotype.Component;
/*
使⽤注解的⽅式配置IOC:
标注了@Component注解表⽰当前类被Spring管理,Spring框架启动的时候就会创建此类的对象到spring容器中去
设置当前Bean的名称:
默认当前Bean的名称就是简单类名的⾸字母⼩写(customerService)
@Component注解的value属性可以⾃定义组件的名称,等价于<bean id/name="bean名称" />
@Component(value="service")表⽰将bean的名称设置service
当注解的属性只有⼀个,并且名为value的时候,可以省略value,
即@Component(value="service")等价于@Component("service")
*/
@Component("service")
public class CustomerService {
public void save() {
System.out.println("-保存数据-");
}
}
--测试代码
Test
public void testSave() {
ApplicationContext context = new ClassPathXmlApplicationContext("l");
CustomerService customerService = (CustomerService) Bean("service");
customerService.save();
}
--测试结果
Spring常⽤注解说明
2.1. ⽤于对象的注解-组件注解
我们将⽤于被扫描创建对象的注解,统称为组件注解。
组件包括:@Controller、@Service、@Repository、@Component。
组件注解的功能就是标识那些在Spring框架启动时,需要创建对象并保存在IOC容器中的类。意味着,只有加了这四个注解中的任何⼀个注解的类,在Spring框架启动的时
候,Spring就通过配置⽂件指定的路径将该路径下的所有带组件注解的类创建对象并且放在容器⾥⾯。
组件注解的功能类似原来配置⽂件的<bean>标签。
问题:明明⼀个@Component注解就可以满⾜了扫描的需要,为什么要有四个呢?
答:其实Spring第⼀版注解的实现(spring 2.5),只有@Component组件注解。从spring3.0以后,作者认为根据分层的需要,把它拆成了四个。为了可以让开发⼈员可见即可得,⼀看到注解,⽴即知道类的性质。所以分成了四个。
@Controller:⽤于声明表⽰层的组件注解
@Service:⽤于声明服务层的组件注解
@Repository:⽤于声明持久层的组件注解
@Component:⽤于声明三层以外的组件注解
问题:那么,这四个注解交换使⽤会报错吗。如:持久层,我放@Service标记。
答:@Controller在SpringMVC⾥⾯有强制的要求,SpringMVC的表⽰层必须使⽤@Controller组件注解。其他情况,⽤乱了是不会报错的,不过我们必须不能⽤乱。不遵守规范,不然别⼈就⽆法跟我们⼀起开发了。
2.1.1. @Scope⽤于设置对象的⽣命周期注解
Xml配置需要配置对象的作⽤范围
<bean id="" class="" scope="作⽤域"/>
如果使⽤注解配置bean,那么bean的作⽤范围也需要使⽤注解配置。
@Scope("作⽤范围")
singleton:单例,在ioc容器中仅存在⼀个Bean实例(默认的scope)。
prototype:多例,每次从容器中调⽤Bean时,都返回⼀个新的实例,即每次调⽤getBean()时 ,相当于执⾏newInstance(),并且ioc容器不会管理多例对象。
request:⽤于web开发,将Bean放⼊request作⽤域中,request.setAttribute("xxx") , 在同⼀个request对象中获取同⼀个Bean。
session:⽤于web开发,将Bean 放⼊Session作⽤域中,在同⼀个Session对象中获取同⼀个Bean。
--组件代码
@Component("customerService")
@Scope("singleton")
public class CustomerService {
}
@Service("customerService2")
@Scope("prototype")
public class CustomerService2 {
}
--测试代码
@Test
public void testSave() {
ApplicationContext context = new ClassPathXmlApplicationContext("l");
CustomerService customerService = (CustomerService) Bean("customerService");
CustomerService customerService2 = (CustomerService) Bean("customerService");
System.out.println("singleton: " + (customerService == customerService2));
CustomerService2 customerService3 = (CustomerService2) Bean("customerService2");
CustomerService2 customerService4 = (CustomerService2) Bean("customerService2");
System.out.println("prototype: " + (customerService3 == customerService4));
}
--测试结果
在开发中主要使⽤ scope="singleton"、 scope="prototype"
对于MVC中的Action/Controller使⽤prototype类型,其他使⽤singleton。
2.1.2. @PostConstruct @PreDestroy初始化和销毁⽅法注解
在xml配置中可以配置对象的初始化⽅法和销毁⽅法。
<bean id="someBean" class="org.cjw.pojo.SomeBean"
init-method="init"
destroy-method="destory"/>
如果使⽤注解配置bean,那么bean的作⽤范围也需要使⽤注解配置。
@PostConstruct // 相当于<bean init-method="init" />
public void init() {
System.out.println("初始化⽅法执⾏了");
}
@PreDestroy// 相当于<bean destroy-method="destory" />
public void destory() {
System.out.println("销毁⽅法执⾏了");
}
-
-测试代码
@Test
public void testXml() {
spring ioc注解ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("l");
context.close();
}
--测试结果
⽤于依赖注⼊的注解
回顾:XML配置⽂件使⽤<property name=”” value/ref=””>、<constructor-arg name="" value/ref="" />实现setter注⼊和构造注⼊。通过注⼊注解也可以实现DI。Spring提供了两套注解可以解决对象依赖注
⼊的⽅案:
1. @Autowired +@Qualifier():是Spring定义的标签
2. @Resouce:是JavaEE的规范
2.2.1. @Autowired注解
@Autowired注解:⽤于标识需要依赖注⼊的对象属性。
@Autowired注解贴在字段或者setter⽅法上。
默认情况下@Autowired注解必须要能到对应的对象,否则报错。不过,可使⽤required=false来避免该问题:@Autowired(required=false)
@Autowiredbean的⽅式:
(1) ⾸先按照依赖对象的类型,如果只到⼀个则使⽤字段或者setter⽅法直接注⼊。
(2) 如果在Spring上下⽂中到多个匹配的类型,则再按照名字去,如果没有匹配则报错(NoSuchBeanDefinitionException)。
(3) 可以通过使⽤@Qualifier("otherBean")注解来规定依赖对象按照类型+bean的id去。
使⽤@Autowired注⼊的三种情况
2.2.1.1. 字段注⼊
@Controller("customerController")
public class CustomerController {
// 反射字段直接注⼊:Field.set(obj, value);
@Autowired
private CustomerService customerService;
public void save() {
customerService.save();
}
}
2.2.1.2. setter⽅法注⼊
@Controller("customerController")
public class CustomerController {
private CustomerService customerService;
// 如果将@Autowired放在⽅法的上⾯,意思就是将对象注⼊到该⽅法的参数
// 意味着,spring会⾃动根据参数类型匹配容器中对应的对象给这个⽅法
// 能够使⽤@Autowired注解的⽅法必须是有参数的
@Autowired
public void setCustomerService(CustomerService customerService) {
// 问题:加了@Autowired注解的⽅法在什么时候执⾏?
/
/ 加了@Autowired注解的⽅法在创建完spring容器之后就会⽴即执⾏
System.out.println("-setCustomerService被执⾏了-");
this.customerService = customerService;
}
public void save() {
customerService.save();
}
}
2.2.1.
3. 构造器注⼊
@Controller("customerController")
public class CustomerController {
private CustomerService customerService;
/*
* ⽅式三 : 构造器注⼊
* 使⽤注解的IOC创建bean的情况下
* 默认bean中有什么样的构造器,spring就调⽤那个构造器去创建对应的bean对象
* 并且会⾃动注⼊构造器中对应类型参数的对象
*
* 问题:如果构造函数有多个,默认会⽆参构造
* 解决⽅案:只提供有参构造
*
* 问题:如果构造函数的参数类型对应的bean有多个,会抛出异常
* org.springframework.beans.factory.NoUniqueBeanDefinitionException 不是唯⼀的bean异常
* 解决⽅案:在参数前⾯使⽤ @Qualifier("service1") 注解
* 从多个bean 获取指定 id 对应的bean即可
*/
public CustomerController(@Qualifier("customerService") CustomerService customerService) {
System.out.println("-CustomerController构造器被执⾏了-");
this.customerService = customerService;
}
public void save() {
customerService.save();
}
}
2.2.2. @Qualifier注解
@Qualifier注解:⽤于指定注⼊的对象名,使⽤@Autowired注⼊对象时,@Autowired没有指定对象名的属性,只能通过@Qualifier注解来指定对象名。value属性:指定注⼊Spring容器中对应对象名的对象。
@Controller("customerController")
public class CustomerController {
@Autowired
@Qualifier("customerService")
private CustomerService customerService;
public void save() {
customerService.save();
}
}
2.2.
3. @Resource注解
@Resource注解是Spring框架⽀持Sun官⽅制定的JSR-250标准注⼊对象的实现。
JSR-250就是Sun公司制定,对注⼊的对象的标准。
@Resource功能等同@Autowired + @Qualifier等同配置⽂件标签<proprty name="..." ref="...">
@Resource注解:⽤于给引⽤注⼊容器的对象,可以通过name属性指定对象名。
注意事项:@Resource只能使⽤字段和setter注⼊,不能使⽤构造注⼊。
2.2.
3.1. 字段注⼊
@Controller("customerController")
public class CustomerController {
// 类型+id注⼊
@Resource(name = "customerService")
private CustomerService customerService;
public void save() {
customerService.save();
}
}
2.2.
3.2. setter⽅法注⼊
@Controller("customerController")
public class CustomerController {
private CustomerService customerService;
// 类型+id
@Resource(name = "customerService")
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public void save() {
customerService.save();
}
}
2.2.4. @Value注解
property标签中的value属性只能注⼊基本数据类型、包装类型、String类型。
@Value注解:注⼊基本数据类型以及它们的包装类和String类型数据的,⽀持${}注⼊properties⽂件的键值对,等同 <proprty name="..." value="${Key}" />。
2.2.4.1. 案例代码
--db.properties⽂件(在src路径下创建)
jdbc.sql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/users
jdbc.username=root
jdbc.password=root
jdbc.macActive=10
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论