Spring总结四:IOC和DI 注解方式

首先我们要了解注解和xml配置的区别:

  作用一样,但是注解写在Bean的上方来代替我们之前在xml文件中所做的bean配置,也就是说我们使用了注解的方式,就不用再xml里面进行配置了,相对来说注解方式更为简便。

 

IOC获取对象注解方式:

在我们第二篇(IOC容器配置 xml方式)总结的基础上做修改:

首先我们的applicationContext.xml配置文件要略作修改:(把beans里面加上绿色背景的配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
"><!--开启扫描 扫描包com.zy下面的--><context:component-scan base-package="com.zy"></context:component-scan>
</beans>

然后我们的JavaBean类加上注解(Component):

@Component("bean1")
public class Bean1 {public Bean1() {System.out.println("Bean1的无参构造方法");}
}

这样就代替了我们之前在applicationContext.xml中配置的: <bean id="bean1" class="com.zy.IoC.Bean1"></bean>

测试及运行结果请参照总结第二篇,得出的结果是一样的。

 

Spring 容器还提供@Component 等效三个衍生注解

  • @Repository 用于注册DAO(持久层 )

  • @Service 用于注册 Service(业务层)

  • @Controller 用于注册 Action (表现层)

以@Repository为例:

/*** 测试UserDao接口*/
public interface UserDao {public void getUser();
}
/*** UserDao实现类1*/
@Repository("userDao")
public class UserDaoImpl implements UserDao {public UserDaoImpl() {System.out.println("dao1 构造方法");}@Overridepublic void getUser() {System.out.println("UserDao实现类1  获取用户信息...");}
}

测试:

    @Testpublic void getUser() throws Exception {//根据spring配置文件 获取spring容器ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//使用容器创建UserDao的实现类对象  userDao和配置文件中的 bean的id一致UserDao dao = ac.getBean("userDao", UserDao.class);dao.getUser();}

运行结果:

 

 DI依赖注入注解方式:

注解基本类型属性:这个不多做介绍了

// 基本类型属性
@Value("#{'张学友'}")
private String name;

注解复杂类型属性:

  1,Spring3.0提供@Value注解

    // 复杂类型属性// 第一种 @Value 结合 spEL@Value("#{userDao}")private UserDao userDao;

  2,Spring2.0 提供@Autowired 注解 结合 @Qualifier 注解

    // 第二种 @Autowired 注解 结合 @Qualifier 注解// 如果单独使用@Autowired 默认按照类型注入,如果有多个同一类型的只能找到一个// 使用 @Qualifier 按照名称注入
    @Autowired@Qualifier("userDao")private UserDao userDao;

  3,JSR-250规范 提供 @Resource 注解实现注入(不推荐使用)

    // 第三种 JSR-250提供@Resource 注解// 不写name属性,按照类型注入,写了name属性,按照名称注入@Resource(name = "userDao")private UserDao userDao;

 

以把UserDao注入到UserService为例:

JavaBean代码:

/*** 测试UserDao接口*/
public interface UserDao {public void getUser();
}
/*** UserDao实现类1*/
@Repository("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void getUser() {System.out.println("2 UserDao实现类1  获取用户信息...");}
}/*** UserService接口*/
public interface UserService {public void getUser();
}
/*** UserService实现类*/
@Service("userService")
public class UserServiceImpl implements UserService {//@Autowired+@Qualifier的方式//@Autowired//@Qualifier("userDao")@value("#{userDao}")  //@Value("#{}")的方式     使用注解注入,要与dao实现类的注解一致(使用注解 不需要setter方法,  如果没有构造方法,使用xml配置的时候需要setter方法)private UserDao userDao;@Overridepublic void getUser() {System.out.println("1 业务层1 获取user对象...");userDao.getUser();}
}

测试:

    @Testpublic void getUser() throws Exception {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = ac.getBean("userService", UserService.class);userService.getUser();}

运行结果:

 

其他注解的使用:

生命周期注解:

@PostConstruct 初始化方法

@PreDestroy 销毁方法

//Bean的注解
@Component("springLifeCycle")
public class SpringLifeCycle {//构造方法public SpringLifeCycle() {System.out.println("SpringLifeCycle 构造...");}//初始化方法的注解
    @PostConstructpublic void init() {System.out.println("SpringLifeCycle 初始化...");}//销毁方法的注解
    @PreDestroypublic void destroy() {System.out.println("SpringLifeCycle 销毁...");}public void helloSpring() {System.out.println("hello spring !");}
}

测试:

    @Testpublic void testLifeCycle() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");SpringLifeCycle springLifeCycle = (SpringLifeCycle) ac.getBean("springLifeCycle");springLifeCycle.helloSpring();// 调用close(ApplicationContext没有close方法,需要转子类调用close)ClassPathXmlApplicationContext classAc = (ClassPathXmlApplicationContext) ac;classAc.close();}

运行结果:

 

Bean的作用域注解:

还是上面的JavaBean类:

//Bean的注解
@Component("springLifeCycle")
//作用域注解 prototype为多实例,默认为singleton单实例
@Scope("prototype")
public class SpringLifeCycle {

测试:

    @Testpublic void testScope() throws Exception {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");SpringLifeCycle lifeCycleBean1 = (SpringLifeCycle) applicationContext.getBean("springLifeCycle");SpringLifeCycle lifeCycleBean2 = (SpringLifeCycle) applicationContext.getBean("springLifeCycle");System.out.println(lifeCycleBean1);System.out.println(lifeCycleBean2);// 通过反射 代码调用 close方法Method closeMethod = applicationContext.getClass().getMethod("close");closeMethod.invoke(applicationContext);}

运行结果:

大家会发现销毁方法没有起作用,这里说明一下,Bean必须为singleton单实例的时候,销毁方法才能执行。

将scope设置成singleton:

//Bean的注解
@Component("springLifeCycle")
//作用域注解,singleton为默认值,可以不写这个注解
@Scope("singleton")
public class SpringLifeCycle {

执行结果:

 

转载于:https://www.cnblogs.com/blazeZzz/p/9305861.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

和后台如何对接_业务系统如何对接第三方服务?

在产品工作中&#xff0c;我们时常要对接第三方服务。本文作者从过往的对接项目经历中&#xff0c;提炼的关于业务系统&#xff0c;如何对接第三方服务的方法论&#xff0c;希望能对你有所帮助。随着公司业务的发展&#xff0c;我们有时会遇到&#xff0c;需要在自身业务系统中…

adb 启动某个apk

有时候需要用apk来启动某个apk adb shell am start -n com.android.launcher3/com.android.launcher3.Launcher 具体查看~ /rk3399_7in1/packages/apps/Launcher3/AndroidManifest.xml

Linux_PAM_用户之间的信息传递

PAM 账户信息的验证,可动态加载验证模块,提高验证的灵活性; PAM是一套应用程序接口,提供一连串的验证机制,借由一个与指令程序相同文件名的配置文件进行认证分析. 验证的过程包含三个字段: 1.验证类别(Type): author(认证):检验使用身份,需要密码进行检验account(账户):进行…

将枚举的键值绑定到下拉列表框

控制器代码&#xff1a; ///assemblyString&#xff1a;程序集名称的长格式&#xff0c;name&#xff1a;获取程序集实例中具有指定名称的 System.Type 对象&#xff0c;except&#xff1a;除了哪些枚举&#xff08;键或值都可以&#xff09;不加载到下拉列表框///此方法写在控…

Makefile 文件中的:obj-$(CONFIG_TEST) += test.o,这一类的是什么意思?

1、obj-$ $(CONFIG_TEST) 是一个整体&#xff0c;$(bbb)表示引用变量 bbb 比如定义 CONFIG_TESTy $(CONFIG_TEST) 就是 y obj-$(CONFIG_TEST) 就是 obj-y 又比如定义 CONFIG_TESTm $(CONFIG_TEST) 就是 m obj-$(CONFIG_TEST) 就是 obj-m obj-y foo.o 该例子告诉Kbuild在这目…

C++_IO类型_文件输入输出流_字符串流

IO类型 iostream: 用于窗口的输入输出fstream: 用于文件读写sstream :读写存储在内存中的string对象 注:他们继承于istream与ostream,因此istream对象也可用于读取ifstream, string对象, ostream对象同上; 并且iostream类型可在同一个流实现输入输出操作;. IO对象不可复制赋…

python网络编程证书_python 网络编程——客户端

网络通信的基本接口是socket&#xff0c;它扩展了操作系统的基本I/O到网络网络通信。socket可以通过socket()函数来建立&#xff0c;通过connect()函数来连接。得到了socket&#xff0c;可以确定本地和远程端点的IP地址和端口号。socket对不同的协议来说都是一种通用的接口&…

AC日记——集合位置 洛谷 P1491

集合位置 思路&#xff1a; 次短路&#xff1b; 先走一遍最短路&#xff1b; 记录最短路径&#xff0c;然后依次删边走最短路&#xff1b; 最短的长度就是次短路&#xff1b; 来&#xff0c;上代码&#xff1a; #include <queue> #include <cmath> #include <cs…

Kconfig中的“depends on”和“select”

在Kconfig文件中&#xff1a; config Adepends on Bselect C它的含义是&#xff1a;CONFIG_A配置与否&#xff0c;取决于CONFIG_B是否配置。一旦CONFIG_A配置了&#xff0c;CONFIG_C也自动配置了。 参考资料&#xff1a;“select” vs “depends” in kernel Kconfig。 所以去…

C++_虚继承_虚函数_纯虚函数(多继承的二义性,多态)

基本信息 每一个类都有一个虚表,以及虚表指针; 虚表的内容是编译器决定的,虚表中用于存放虚函数的指针, 程序运行时的类型信息等; 每个多态对象都存放着一个指向当前类型的虚表的指针, 该指针在构造函数中被赋值, 一般来说当调用当前这个类的构造函数, 则虚表指针就指向当前类…

数组的合并和升序排列_leetcode 33 搜索旋转排序数组

给你一个升序排列的整数数组 nums &#xff0c;和一个整数 target 。假设按照升序排序的数组在预先未知的某个点上进行了旋转。&#xff08;例如&#xff0c;数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] &#xff09;。请你在数组中搜索 target &#xff0c;如果数组中存在…

[LeetCode] [C++] 206 Reverse Linked List 反转单项链表

题目要求 Reverse a singly linked list.LeetCode 206在线测试 问题描述 给定一个单项链表&#xff0c;将其反转后返回链表头节点。 思路分析1 可以完整的遍历一遍链表&#xff0c;将链表的每个节点的值存在数组中&#xff0c;然后反向遍历数组重新生存一个新 链表。这样做需要…

defconfig、 .config

最近在裁剪内核慢慢关注这个问题 defconfig、 .config defconfig 一般在arch/arm64/configs/目录下&#xff0c;是一个简单的内核配置&#xff0c;是没有展开的。 .config一般是用来执行make menuconfig的基础配置 从.config到defcong不是简单的复制操作&#xff0c;而是mak…

递归过程中语句执行顺序

递归的两种模式 模式一 //递归的过程中在"递"的过程中解决问题 function function_name(Max_argument){if(end_condition){end;}else{solve;function_name(Min_argument);//问题规模逐渐减小} } 注:位于递归函数前的语句和函数具有顺序性 模式二 //递归的过程中…

qq面板(仿版,未完待续中。。。。)---2017-04-24

主要实现效果&#xff1a; 1、点击对话&#xff0c;显示对话&#xff1b;点击联系人&#xff0c;显示联系人 2、在联系人界面&#xff1a; 实现好友列表的展开与折叠&#xff1b;&#xff08;图12&#xff09; 实现鼠标移到好友列表上的背景颜色的变化&#xff1b;&#xff08;…

苹果企业证书_苹果签名经常掉签原因大汇总

苹果签名就是数字签名&#xff0c;是基于非对称加密算法来实现的&#xff0c;对称加密就是通过非对称加密算法实现的&#xff0c;对称加密是通过同一份秘钥加密解密数据&#xff0c;非对称加密有两份秘钥&#xff0c;分别是公钥和私钥&#xff0c;用公钥进行加密的数据只能使用…

漫画|Linux 并发、竞态、互斥锁、自旋锁、信号量都是什么鬼?

1. 锁的由来&#xff1f;学习linux的时候&#xff0c;肯定会遇到各种和锁相关的知识&#xff0c;有时候自己学好了一点&#xff0c;感觉半桶水的自己已经可以华山论剑了&#xff0c;又突然冒出一个新的知识点&#xff0c;我看到新知识点的时候&#xff0c;有时间也是一脸的懵逼…

C++_顺序容器

顺序容器类型 顺序容器 vector: 支持快速随机访问list: 支持快速插入与删除deque: 双端队列 顺序适配器 - stack: 后进先出(LIFO)堆栈 - queue: 先进先出(FIFO)队列 - priority_queue: 有优先级管理的队列 上述顺序容器包含于以下头文件中:< vector >,< list &…

python画tan_Python入门之三角函数tan()函数实例详解

描述tan() 返回x弧度的正弦值。语法以下是 tan() 方法的语法:import mathmath.tan(x)注意&#xff1a;tan()是不能直接访问的&#xff0c;需要导入 math 模块&#xff0c;然后通过 math 静态对象调用该方法。参数x -- 一个数值。返回值返回x弧度的正弦值&#xff0c;数值在 -1 …

课程作业一

由于代码的难点部分是王源写的。。所以开始我选择了重写。。但是重写好像比我想象的复杂太多&#xff0c;加上时间分配不够所以现在还没有完成。。先提交随笔写好后补上代码。。我道歉认罚。。把这次当成一个教训。。 转载于:https://www.cnblogs.com/daydreams/p/6759372.html…