Spring 管理 Bean-IOC--基于注解配置 bean

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Spring 管理 Bean-IOC--基于注解配置 bean

Spring 管理 Bean-IOC--基于注解配置 bean

● 基本介绍

基于注解的方式配置 bean, 主要是项目开发中的组件,比如 Controller、Service、和 Dao.

● 组件注解的形式有

1. @Component 表示当前注解标识的是一个组件

2. @Controller 表示当前注解标识的是一个控制器,通常用于 Servlet

3. @Service 表示当前注解标识的是一个处理业务逻辑的类,通常用于 Service 类

4. @Repository 表示当前注解标识的是一个持久化层的类,通常用于 Dao 类

代码演示--了解注解

创建UserDao  UserService UserAction MyComponent类来方便了解

UserDao  

@Repository

public class UserDao { }

UserService

@Service

public class UserService { }

UserAction

@Controller

public class UserAction { }

MyComponent

@Component

public class MyComponent { }

 配置 beans.xml

1. component-scan 要对指定包下的类进行扫描, 并创建对象到容器

2. base-package 指定要扫描的包

3. 含义是当spring容器创建/初始化时,就会扫描com.spring.component包

下的所有的 有注解 @Controller / @Service / @Respository / @Component类将其实例化,生成对象,放入到ioc容器

4. resource-pattern="User*.class" 表示只扫描com.spring.component 和它的子包下User打头的类

<?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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--配置容器要扫描的包
    1. component-scan 要对指定包下的类进行扫描, 并创建对象到容器
    2. base-package 指定要扫描的包
    3. 含义是当spring容器创建/初始化时,就会扫描com.wyxedu.spring.component包
       下的所有的 有注解 @Controller / @Service / @Respository / @Component类
       将其实例化,生成对象,放入到ioc容器
    4. resource-pattern="User*.class" 表示只扫描com.wyxedu.spring.component 和它的子包下的User打头的类
    -->
    <!--<context:component-scan base-package="com.spring.component"/>-->
    <!--
        需求:如果我们希望排除某个包/子包下的某种类型的注解,可以通过exclude-filter来指定
        1. context:exclude-filter 指定要排除哪些类
        2. type 指定排除方式 annotation表示按照注解来排除
        3. expression="org.springframework.stereotype.Service" 指定要排除的注解的全路径
    -->
    <!--<context:component-scan base-package="com.spring.component">-->
    <!--    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
    <!--    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>-->
    <!--</context:component-scan>-->
    <!--
        需求:如果我们希望按照自己的规则,来扫描包/子包下的某些注解, 可以通过 include-filter
        1. use-default-filters="false" 表示不使用默认的过滤机制/扫描机制
        2. context:include-filter 表示要去扫描哪些类
        3. type="annotation" 按照注解方式来扫描/过滤
        4. expression="org.springframework.stereotype.Service" 指定要扫描的注解的全路径
    -->
    <context:component-scan base-package="com.spring.component" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

注意

如果我们希望排除某个包/子包下的某种类型的注解,可以通过exclude-filter来指定

       1. context:exclude-filter 指定要排除哪些类

       2. type 指定排除方式 annotation表示按照注解来排除

       3. expression="org.springframework.stereotype.Service" 指定要排除的注解的全路径

如果我们希望按照自己的规则,来扫描包/子包下的某些注解, 可以通过 include-filter

       1. use-default-filters="false" 表示不使用默认的过滤机制/扫描机制

       2. context:include-filter 表示要去扫描哪些类

       3. type="annotation" 按照注解方式来扫描/过滤

       4. expression="org.springframework.stereotype.Service" 指定要扫描的注解的全路径

测试

  //通过注解来配置Bean
    @Test
    public void setBeanByAnnotation() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans05.xml");
        UserDao userDao = ioc.getBean(UserDao.class);
        //在默认情况下, 注解标识的类创建对象后,在容器中,id 为类名的首字母小写
        UserDao userDao1 = ioc.getBean("userDao", UserDao.class);
        System.out.println("userDao1=" + userDao1);
        UserService userService = ioc.getBean(UserService.class);
        UserAction userAction = ioc.getBean(UserAction.class);
        MyComponent myComponent = ioc.getBean(MyComponent.class);
        System.out.println("userDao=" + userDao);
        System.out.println("userService=" + userService);
        System.out.println("userAction=" + userAction);
        System.out.println("myComponent=" + myComponent);
        System.out.println("ok");
    }

注意事项和细节说明

1. 需要导入 spring-aop-5.3.8.jar , 别忘了

2. 必须在 Spring 配置文件中指定"自动扫描的包",IOC 容器才能够检测到当前项目中哪些类被标识了注解, 注意到导入 context 名称空间

可以使用通配符 * 来指定 ,比如 com.spring.* 表示

提问: com.spring.component 会不会去扫描它的子包?

答:会的

Spring 的 IOC 容器不能检测一个使用了@Controller 注解的类到底是不是一个真正的控制器。

注解的名称是用于程序员自己识别当前标识的是什么组件。

其它的@Service   @Repository 也是一样的道理 [也就是说 spring 的 IOC 容器只要检查到注解就会生成对象,

但是这个注解的含义 spring 不会识别,注解是给程序员编程方便看的]

默认情况:标记注解后,类名首字母小写作为 id 的值。也可以使用注解的 value 属性 指定 id 值,

并且 value 可以省略。

@Controller(value="userAction01")

@Controller("userAction01")

自动装配

基本说明

1. 基于注解配置 bean,也可实现自动装配,使用的注解是:@AutoWired 或者 @Resource

2. @AutoWired 的规则说明

1) 在 IOC 容器中查找待装配的组件的类型,如果有唯一的 bean 匹配,则使用该 bean 装配

2) 如待装配的类型对应的 bean 在 IOC 容器中有多个,则使用待装配的属性的属性名作为 id 值再进行查找, 找到就装配,找不到就抛异常

3. @Resource 的规则说明

1) @Resource 有两个属性是比较重要的,分是 name 和 type,Spring 将@Resource 注解的name 属性解析为 bean 的名字,

而 type 属性则解析为 bean 的类型.所以如果使用 name 属性,则使用 byName 的自动注入策略,

而使用 type 属性时则使用 byType 自动注入策略

2) 如果@Resource 没有指定 name 和 type ,

则先使用byName注入策略, 如果匹配不上,再使用 byType 策略, 如果都不成功,就会报错

4. 建议,不管是@Autowired 还是 @Resource 都保证属性名是规范的写法就可以注入.

应用实例需求

1. 以 Action/Service/Dao 几个组件来进行演示

2. 这里就演示 UserAction 和 UserService 的两级自动组装

UserService

@Service
public class UserService {
public void hi(){
System.out.println("UserService hi()~");
}
}

UserAction

@Controller
public class UserAction {
    //xml配置 ref
    //说明 @Autowired
    //1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean匹配(按照类型),则使用该bean装配
    //2)如待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值再进行查找,
    //  找到就装配,找不到就抛异常
    //说明 @Resource
    //1) @Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,
    //  而type属性则解析为bean的类型.所以如果使用name属性,则使用byName的自动注入策略,
    //  而使用type属性时则使用byType自动注入策略
    //  比如@Resource(name = "userService") 表示装配 id=userService对对象
    //  比如@Resource(type = UserService.class) 表示按照UserService.class类型进行装配, 这时要求容器中,只能有一个这样类型的对象
    //2) 如果@Resource 没有指定 name 和 type ,则先使用byName注入策略,
    //   如果匹配不上, 再使用byType策略, 如果都不成功,就会报错
    //=================================
    //说明: @Autowired + @Qualifier(value = "userService02") 组合也可以完成指定 name/id 来进行自动装配
    //指定id进行组装, 也可以使用@Autowired 和 @Qualifier(value = "userService02")
    // 这时,是装配的 id=userService02 , 需要两个注解都需要写上
    @Resource
    private UserService userService;
    public void sayOk() {
        System.out.println("UserAction 的sayOk()");
        System.out.println("userAction 装配的 userService属性=" + userService);
        userService.hi();
    }
}

配置.xml

    <context:component-scan
            base-package="com.spring.component"/>
    <!--配置两个UserService对象-->
    <bean class="com.wyxedu.spring.component.UserService" id="userService200"/>
    <bean class="com.wyxedu.spring.component.UserService" id="userService300"/>

测试

 public void setProByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
        UserService userService = ioc.getBean("userService", UserService.class);
        System.out.println("ioc容器中的userService=" + userService);
            UserService userService200 = ioc.getBean("userService200", UserService.class);
        System.out.println("ioc容器中的userService200=" + userService200);
        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        //System.out.println("userAction=" + userAction);
        userAction.sayOk();
    }   

注意事项和细节说明

注意事项和说明

xml配置 ref

@Autowired

       1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean匹配(按照类型),则使用该bean装配

       2)如待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值再进行查找,

找到就装配,找不到就抛异常

@Resource

       1) @Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,

而type属性则解析为bean的类型.所以如果使用name属性,则使用byName的自动注入策略,

而使用type属性时则使用byType自动注入策略

比如@Resource(name = "userService") 表示装配 id=userService对对象

比如@Resource(type = UserService.class) 表示按照UserService.class类型进行装配, 这时要求容器中,只能有一个这样类型的对象

2) 如果@Resource 没有指定 name 和 type ,则先使用byName注入策略,如果匹配不上, 再使用byType策略, 如果都不成功,就会报错

说明:

@Autowired + @Qualifier(value = "userService02") 组合也可以完成指定 name/id 来进行自动装配指定id进行组装, 也可以使用@Autowired 和 @Qualifier(value = "userService02")

这时,是装配的 id=userService02 , 需要两个注解都需要写上

泛型依赖注入

● 基本说明

1. 为了更好的管理有继承和相互依赖的 bean 的自动装配,spring 还提供基于泛型依赖的注入机制

2. 在继承关系复杂情况下,泛型依赖注入就会有很大的优越性

各个类关系图

传统方法是将 PhoneDao /BookDao 自动装配到 BookService/PhoneSerive 中,当这 种继承关系多时,就比较麻烦,可以使用 spring 提供的泛型依赖注入

创建Book类

public class Book {}

创建Phone类

public class Phone{}

创建BaseDao类

public abstract void save();

 创建BookDao类

@Repository
public class BookDao extends BaseDao<Book>{
    @Override
    public void save() {
        System.out.println("BookDao 的 save()..");
    }
}

创建PhoneDao类

@Repository
public class PhoneDao extends BaseDao<Phone>{
    @Override
    public void save() {
        System.out.println("PhoneDao save()");
    }
}

创建BaseService类

public class BaseService<T> {
    @Autowired
    private BaseDao<T> baseDao;
    public void save() {
        baseDao.save();
    }
}

创建BookService类

@Service
public class BookService extends BaseService<Book>{
    //并没有写属性
}

创建PhoneService类

@Service
public class PhoneService extends BaseService<Phone>{
}

修改xml配置

    <context:component-scan base-package="com.spring.depinjection"/>

测试

    @Test
    public void setProByDependencyInjection() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans07.xml");
        PhoneService phoneService = ioc.getBean("phoneService", PhoneService.class);
        phoneService.save();
        System.out.println("ok");
    }


目录
相关文章
|
1月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
157 26
|
3天前
|
JSON 前端开发 Java
Spring MVC常用的注解
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中 的所有响应请求的方法都是以该地址作为父路径。 @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。 @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。 @Controller:控制器的注解,表示是表现层,不能用用别的注解代替 @RestController : 组合注解 @Conntroller + @ResponseBody @GetMapping , @PostMapping , @Put
|
3天前
|
Java Spring
Spring Boot的核心注解是哪个?他由哪几个注解组成的?
Spring Boot的核心注解是@SpringBootApplication , 他由几个注解组成 : ● @SpringBootConfiguration: 组合了- @Configuration注解,实现配置文件的功能; ● @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项 ● @ComponentScan:Spring组件扫描
|
2天前
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
19 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
5天前
|
Java 测试技术 Spring
SpringBoot+@Async注解一起用,速度提升
本文介绍了异步调用在高并发Web应用性能优化中的重要性,对比了同步与异步调用的区别。同步调用按顺序执行,每一步需等待上一步完成;而异步调用无需等待,可提升效率。通过Spring Boot示例,使用@Async注解实现异步任务,并借助Future对象处理异步回调,有效减少程序运行时间。
|
2天前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
10 0
|
2天前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
15 0
|
2天前
|
Java 数据库连接 数据库
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——MyBatis 介绍和配置
本文介绍了Spring Boot集成MyBatis的方法,重点讲解基于注解的方式。首先简述MyBatis作为持久层框架的特点,接着说明集成时的依赖导入,包括`mybatis-spring-boot-starter`和MySQL连接器。随后详细展示了`properties.yml`配置文件的内容,涵盖数据库连接、驼峰命名规范及Mapper文件路径等关键设置,帮助开发者快速上手Spring Boot与MyBatis的整合开发。
15 0
|
2天前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th=&quot;http://www.thymeleaf.org&quot;`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
16 0
|
2天前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
15 0