本篇文章继续上篇文章讲解 IoC 基础, 这篇文章主要介绍使用 spring 注解配置 IoC
上篇文章主要是通过 xml 配置文件进行 IoC 的配置. 这次进行改造下, 通过注解进行配置
首先先看一个简单的 demo
简单 demo
构建 maven 项目
pom 文件如下
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>4.3.0.RELEASE</spring.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- <version>4.10</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>1.8.9</version>
- </dependency>
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>3.2.4</version>
- </dependency>
- </dependencies>
BookDao.java
- package com.kevin.spring.demo1.dao;
- /**
- * 书籍 dao
- */
- public interface BookDao {
- /**
- * 添加图书
- * @param book
- * @return
- */
- String addBook(String book);
- }
BookDaoImpl.java
- package com.kevin.spring.demo1.dao.impl;
- import com.kevin.spring.demo1.dao.BookDao;
- import org.springframework.stereotype.Component;
- /**
- * 图书实现类
- */
- @Component(value = "book")
- public class BookDaoImpl implements BookDao {
- public String addBook(String book) {
- return "添加图书" + book + "成功";
- }
- }
在类的开头使用了 @Component 注解, 它可以被 Spring 容器识别, 启动 Spring 后, 会自动把它转成容器管理的 Bean.id 为 book. 注意这里我指定了 value 值
book.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">
- <context:component-scan base-package="com.kevin.spring.demo1"></context:component-scan>
- </beans>
这里 增加了注解扫描的范围, 指定了 demo1 包
测试业务类
- package com.kevin.spring.demo1.service;
- import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- /**
- * 业务类
- */
- public class BookService {
- private BookDaoImpl bookDao;
- public void addBook(String bookName) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
- bookDao = ctx.getBean("book", BookDaoImpl.class);
- String resout = bookDao.addBook(bookName);
- System.out.println(resout);
- }
- public static void main(String[] args) {
- new BookService().addBook("JAVA");
- }
- }
运行结果
信息: Loading xml bean definitions from class path resource [book.xml]
添加图书 JAVA 成功
我们已经完成一个简单的 demo, 当然只学习这些是不够的, 我们还要继续挖掘每个细节
@Component 注解
上面的 demo 中我们指定了一个 value 值, 如果不指定 value 值的话, 他默认是什么呢?
修改 BookDaoImpl.java 文件, 将 value 值删除
- /**
- * 图书实现类
- */
- @Component
- public class BookDaoImpl implements BookDao {
- public String addBook(String book) {
- return "添加图书" + book + "成功";
- }
- }
修改测试类
- package com.kevin.spring.demo1.service;
- import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- /**
- * 业务类
- */
- public class BookService {
- private BookDaoImpl bookDao;
- public void addBook(String bookName) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
- bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
- String resout = bookDao.addBook(bookName);
- System.out.println(resout);
- }
- public static void main(String[] args) {
- new BookService().addBook("JAVA");
- }
- }
注意下, getBean() 方法部分
运行结果
信息: Loading xml bean definitions from class path resource [book.xml]
添加图书 JAVA 成功
结果证明, 如果没有写 value 的话, 默认是该类名字且首字母小写
xml 配置文件
- <context:component-scan base-package="com.kevin.spring.demo1" resource-pattern="">
- <context:exclude-filter type=""expression=""></context:exclude-filter>
- <context:include-filter type=""expression=""></context:include-filter>
- </context:component-scan>
如上面代码所示
resource-pattern: 对指定的基包下面的子包进行选取
include-filter: 指定需要包含的包
exclude-filter: 指定需要排除的包
expression: 表示过滤的表达式
type : 表示采的过滤类型 共 5 种类型 (如下所示)
Filter Type | Examples Expression | Description | |
---|---|---|---|
annotation | org.example.SomeAnnotation | 注解了 SomeAnnotation 的类 | |
assignable | org.example.SomeClass | 所有扩展或者实现 SomeClass 的类 | |
aspectj | org.example..*Service+ | AspectJ 语法表示 org.example 包下所有包含 Service 的类及其子类 | |
regex | org.example.Default.* | Regelar Expression,正则表达式 | |
custom | org.example.MyTypeFilter | 通过代码过滤,实现 org.springframework.core.type.TypeFilter 接口 |
作用域 scope
上篇文章, 我们知道在 xml 中 bean 中可以配置 scope 且默认为 singletion, 我们看看采用注解的时候是不是默认也是 singleton
修改代码
- public class BookService {
- private BookDaoImpl bookDao;
- private BookDaoImpl bookDao1;
- public void addBook(String bookName) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
- bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
- bookDao1 = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
- System.out.println(bookDao == bookDao1);
- String resout = bookDao.addBook(bookName);
- System.out.println(resout);
- }
- public static void main(String[] args) {
- new BookService().addBook("JAVA");
- }
- }
运行结果
true
添加图书 JAVA 成功
如果我想要修改 scope 怎么弄呢?
可以增加 @Scope(value ="prototype" ), 增加后运行结果为 false
Lazy 延迟初始化 Bean
xml 中可以设置延迟加载 bean, 当然注解也有
@Lazy
初始化回调注解
@PostConstruct 初始化方法的注解方式 等同与在 xml 中声明 init-method=init
销毁回调
@PreDestroy 销毁方法的注解方式 等同于在 xml 中声明 destory-method=destory
自动装配
上面的代码中, 我们都用了 ApplicationContext 初始化容器后获得需要的 Bean, 可以通过自动装配简化
- package com.kevin.spring.demo1.service;
- import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.stereotype.Component;
- import org.springframework.stereotype.Service;
- import javax.annotation.Resource;
- /**
- * 业务类
- */
- @Service
- public class BookService {
- @Resource
- private BookDaoImpl bookDao;
- @Resource
- private BookDaoImpl bookDao1;
- public void addBook(String bookName) {
- // ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
- // bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
- // bookDao1 = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
- System.out.println(bookDao == bookDao1);
- String resout = bookDao.addBook(bookName);
- System.out.println(resout);
- }
- public static void main(String[] args) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
- BookService bookService = ctx.getBean(BookService.class);
- bookService.addBook("好好学习");
- }
- }
@Service 用于注解业务层组件
@Controller 用于注解控制层组件
@Repository 用于注解数据访问组件, 即 DAO 组件
@Component 泛指组件, 当组件不好归类的时候, 我们可以使用这个注解进行注解.
装配注解主要有:@Autowired,@Qualifie,@Resource, 它们的特点是:
@Resource 默认是按照名称来装配注入的, 只有当找不到与名称匹配的 bean 才会按照类型来装配注入;
@Autowired 默认是按照类型装配注入的, 如果想按照名称来转配注入, 则需要结合 @Qualifier 一起使用;
@Resource 注解是又 J2EE 提供, 而 @Autowired 是由 spring 提供, 故减少系统对 spring 的依赖建议使用 @Resource 的方式; 如果 Maven 项目是 1.5 的 JRE 则需换成更高版本的.
@Resource 和 @Autowired 都可以书写注解在字段或者该字段的 setter 方法之上
好了, 这篇文章就暂时写到这, 大家玩的开心.
代码: https://github.com/runzhenghengbin/spring-study
参考: https://www.cnblogs.com/best/p/5727935.html#_label3
来源: https://www.cnblogs.com/zhenghengbin/p/10098361.html