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

news/2024/10/17 16:18:31/

目录

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

● 基本介绍

● 组件注解的形式有

代码演示--了解注解

UserDao  

 UserService 

 UserAction 

 MyComponent

  配置 beans.xml

 注意

测试

 

注意事项和细节说明

自动装配

基本说明

应用实例需求

UserService 

UserAction

配置.xml

测试

 

注意事项和细节说明

注意事项和说明

@Autowired

@Resource

说明:

泛型依赖注入

● 基本说明

各个类关系图

创建Book类

创建Phone类

 创建BaseDao类

  创建BookDao类

创建PhoneDao类

创建BaseService类

创建BookService类

创建PhoneService类

修改xml配置

 测试


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.hspedu.spring.component包
下的所有的 有注解 @Controller / @Service / @Respository / @Component类将其实例化,生成对象,放入到ioc容器
4. resource-pattern="User*.class" 表示只扫描com.hspedu.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.hspedu.spring.component包下的所有的 有注解 @Controller / @Service / @Respository / @Component类将其实例化,生成对象,放入到ioc容器4. resource-pattern="User*.class" 表示只扫描com.hspedu.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-filter1. 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@Testpublic 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 名称空间

<!-- 配置自动扫描的包 -->

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

可以使用通配符 * 来指定 ,比如 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 , 需要两个注解都需要写上@Resourceprivate UserService userService;public void sayOk() {System.out.println("UserAction 的sayOk()");System.out.println("userAction 装配的 userService属性=" + userService);userService.hi();}
}

配置.xml

    <context:component-scanbase-package="com.spring.component"/><!--配置两个UserService对象--><bean class="com.hspedu.spring.component.UserService" id="userService200"/><bean class="com.hspedu.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<T>类

public abstract void save();

  创建BookDao类

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

创建PhoneDao类

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

创建BaseService类


public class BaseService<T> {@Autowiredprivate 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"/>

 测试

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


http://www.ppmy.cn/news/55604.html

相关文章

Linux系统主要目录

Linux系统中主要的目录&#xff0c;其中某些目录在不同的Linux发行版中可能有所不同。 目录名称作用bin存放常用命令boot存放引导系统相关的文件dev存放设备文件etc存放系统配置文件home存放用户的主目录lib存放系统共享库lib64存放系统共享库&#xff0c;用于64位系统lostfou…

bito ai 使用vue2 写一个弹框插件

使用vue2&#xff0c;写一个消息弹框的插件&#xff0c;使用vue.use()导入插件&#xff0c;要求插件全局可使用&#xff0c;使用this就可以在vue页面调用&#xff0c;这个消息弹窗有两个按钮&#xff0c;一个取消&#xff0c;一个确定&#xff0c;点击取消消息提示消失&#xf…

解决安卓中RecyclerView当一项被点击之后,后面每间隔相同的一段都会有其它项被点击

文章目录 问题描述缘由解决办法 1&#xff1a;提高缓存容量解决办法 2&#xff1a;每次在初始化视图数据之前重置视图数据解决办法 3&#xff1a;优化设计&#xff0c;不在视图中储存数据 问题描述 安卓开发会有很多很多莫名其妙的坑。笔者在使用 RecyclerView 的过程中&#x…

PHP面试宝典之Redis下篇

redis主从同步&#xff1f; 全量同步&#xff1a; 什么时候进行全量同步&#xff1f; 1&#xff1a;从节点第一次连接主节点时 2&#xff1a;从节点断开时间太久&#xff0c;日志中的offset被覆盖时 全量同步的过程&#xff1f; 1&#xff1a;从节点请求增量同步 2&…

Word论文自动化排版

论文的总体结构包含了标题、正文、子标题、图形、公式、算法、表格、参考文献等子结构。在利用Word进行论文排版时常常遇到这些困难&#xff1a;&#xff08;1&#xff09;论文的各子结构的格式非常难以做到统一&#xff0c;而且一旦某一子结构的格式需要修改&#xff0c;则需要…

Linux从入门到精通一般要学习多久?

如果一般操作的话&#xff0c;很简单学会&#xff0c;用不了多长时间&#xff0c;和一般的window操作系统一样具有图形界面&#xff0c;操作起来十分方便&#xff0c;Linux中也有WPS办公系统&#xff0c;、Linux上的应用程序没有windows上那么丰富&#xff0c;但也能满意一般用…

一些关于单链表的操作

思维导图&#xff1a; 一&#xff0c; 链表 1.1节点的结构 链表是啥样的啊&#xff1f;顾名思义链表就是一种用链子链接起来的表。那这种表是怎么样的啊&#xff1f; 这样的呗&#xff1a; 现在&#xff0c;我们知道了链表的形状了。那我们该如何用编程语言来形成这一种形状…

倾斜摄影超大场景的三维模型轻量化纹理压缩的关键技术

倾斜摄影超大场景的三维模型轻量化纹理压缩的关键技术 倾斜摄影超大场景的三维模型轻量化处理中纹理压缩是轻量化处理的重要手段之一&#xff0c;可以在保证模型真实感的前提下&#xff0c;减小数据体积、降低传输带宽和提高渲染性能。以下是几个关键的纹理压缩技术&#xff1a…