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

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在这目…

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。 所以去…

数组的合并和升序排列_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;然后反向遍历数组重新生存一个新 链表。这样做需要…

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;有时间也是一脸的懵逼…

不废话~就是抽奖~

不废话就是抽奖 在公众号回复-抽奖- 获取抽奖二维码参与抽奖

威纶触摸屏与电脑连接_PLC与这7种设备的连接方式,一看就懂!

点击上方电工小青年&#xff0c;关注并星标专业的电工电气领域自媒体&#xff0c;不容错过欢迎转发朋友圈~PLC常见的输入设备有按钮、行程开关、接近开关、转换开关、拨码器、各种传感器等&#xff0c;输出设备有继电器、接触器、电磁阀等。正确地连接输入和输出电路&#xff0…

Android studio JNI jni实例

1.Jni的作用 1.Jni的作用 Java是一种比较高级的语言&#xff0c;Java调用c库&#xff0c;调用c库是必不可少的&#xff0c;所以Jni就应运而生了。看了这个文章的同学&#xff0c;应该能够自己写个APK装在自己的手机里面吧&#xff0c;以前刚开始做android的时候&#xff0c;写…

二叉树先序遍历,中序遍历,后序遍历,层次遍历学习总结及完整C/C++代码

伪代码阐述 先序遍历 先序遍历:先访问根节点, 然后深入左子树,直到不能深入时再深入右子树 由定义可得递归式 void travPre_R(BinNodePosi* x,VISIT& visit){if(!X) return; //到达叶子节点,开始回归visit(x->data);//向左子树深入的过程中便开始进行对每个节点的数据…

nedc工况_东南DX3 EV续航升级 NEDC综合工况续航451公里

东南DX3 EV续航升级版车型曝光&#xff0c;电池系统能量密度由之前的141Wh/kg提升至了161Wh/kg&#xff0c;NEDC综合工况续航也由老款产品的351km提升至了451km。近日&#xff0c;工信部公布了2019年第7批《新能源汽车推广应用推荐车型目录》&#xff0c;东南DX3 EV续航升级版车…

不笑找我系列 | 程序员爆笑漫画十条

原创翻译~ 转载请说明出处~~~~~~~~ 1、如果你让码农给你做个事情&#xff0c;比如修个灯泡&#xff0c;他会这样去执行你的指令 2、分享一个码农发现并解决bug的过程&#xff0c;实在是符合我们码农的人设 3、码农的一天&#xff0c;像极了我的一天 4、至今为止&#xff0c;没…

AVL树学习总结

AVL树 平衡二叉树的缺点 由于平衡二叉搜索树的search(), insert(),remove()接口的运行时间与二叉树的高度成正比,所以若不能有效控制树高, 从平均复杂度来看,二叉平衡搜索树并不能让人满意 理想平衡 二叉树的性能取决于树的高度,只有当左右子树的高度接近时才能达到理想平衡…

nginx编译安装_Nginx编译安装nginx-upsync-module模块以实现动态负载

安装依赖包OpenSSL在官网下载页下到最新稳定版1.0.2q。PCRE在 PCRE 官网可以找到下载地址&#xff0c;这里选择8.x的最高版本 pcre-8.42.tar.gz。zlibzlib 直接选择官网首页最新的zlib-1.2.11.tar.gz。下载nginx 源码包及nginx-upsync-module模块源码这里下载的是nginx稳定版ng…

码农笑话图片十张

原创翻译~转载请说明出处~~~~~~~~1、如果你让码农给你做个事情&#xff0c;比如修个灯泡&#xff0c;他会这样去执行你的指令2、分享一个码农发现并解决bug的过程&#xff0c;实在是符合我们码农的人设3、码农的一天&#xff0c;像极了我的一天4、至今为止&#xff0c;没有遇到…

伸展树学习总结

伸展树 与AVL树类似, 伸展树也是二叉搜索树的一种形式, 伸展树无需保证时刻保持全树的平衡,也不需要像AVL树一样要求记录平衡因子的附加信息 伸展树的提出源于信息访问的局部性(刚被访问过的信息有可能再次被访问,要被访问的元素可能位于刚访问过的元素的附近), 就伸展树而言…

c语言 库打印函数

函数#include<stdio.h>int printf(const char *format, ... );/* [until c99]写结果到stdout */int printf(const char *restrict format, ... );/* [since c99] */int fprintf(FILE *stream, const char *format, ... );/* [until c99]写结果到文件流stream */int fprin…