博主在上一篇文章中提过xml配置文件的一个标签bean
这里提供一个连接 spring学习笔记贰——IOC/DI
我们就来讲讲关于bean的一些知识
在spring框架中,java程序在扫描applicationContext的时候,封装的dom4l解析器会按照引用bean约束去加载和解析bean标签下的内容,并将解析到的结果交给java虚拟机处理,然后处理后的信息返还给开发者
bean的生命周期
第一个阶段:初始化
spring框架在解析bean标签的时候,底层类会调用init()方法让bean进行初始化,
第二个阶段:参数传入阶段
初始化的时候,bean会查找自身有没有经过配置文件注入参数的情况,也就是有没有property或者constructor-arg标签,有的话会将值随着初始化传入相关java类参数中,最终将初始化后的对象返还给开发者
第三个阶段:实现接口方法
在spring框架中提供了一写接口供开发者去实现里面的方法,这里博主列举了一些及其作用
BeanNameAware ---> 获取bean里面的id值
BeanFactoryAware ---> 使用beanfactory的方法
ApplicationContext ---> 使用applicacontext的方法
BeanPostProcessor ---> 在初始化之前和之后进行点操作
emmmmmm~~,博主还是实现选择其中一个方法去实现吧
这里我使用user类选择实现BeanNameAware接口
在applicationContext.xml中配置user的bean
执行测试程序
可以得出结果:
第四个阶段
销毁bean
Bean标签常用属性
(1)id属性
其名称,id属性值名称任意,但是不能写中文,还有特殊符号
根据id值得到配置对象
(2)class属性
创建对象所在类的路径
(3)name属性
功能和id属性一样的
值里面可以包含特殊符号
目前没用
存在是为了兼容schema 1版本
(4)scope属性(范围)
singleton:默认值,单例的
通过getbean生成的对象只有一个,而且不管getbean对象,对象都唯一
测试代码如下:
测试结果如下:
prototype:多例的
通过getbean生成的对象都不同
测试结果如下:
request:创建对象把对象放到request域里面
session:创建对象把对象放在session域里面
globalSession:创建对象把对象放在globalSession域里面
一般只用前面两个,后三个很少用
(5)lazy-init属性:延时初始化true/false
(6)init-method属性:bean被实例化后立刻执行的方法,后面接方法名
(7)destory-method属性:当容器被正常关闭的时候执行的方法
到这里,肯定出现一些问题,如果说每一个类都要用bean来配置的话,岂不是非常麻烦?
所以,spring框架就有一个注解机制来应对这种情况,
spiring的bean管理(注解)
注解介绍
1、代码里面特殊的标记,使用注解可以完成功能
2、注解写法:@注解名称(属性名称=属性值)
3、注解使用在类上面,方法上面和属性上面
Spring注解开发准备
注解可以替代配置文件,但不可以完全替代配置文件
注解的效果相当于在原来的配置文件加上给相应的类配置bean
注解可以实现对对象的创建
1、导入jar包
(1)导入基本的jar包
(2)导入aop jar包
2、创建类,创建方法
博主先来创建一个user类并给他一个简单的方法,至于使用的话下面会用
3、创建spring配置文件,引入约束
(1)做ioc基本功能时,引入beans约束
(2)做spring的ioc注解开发时,除了beans约束外,还需要加入新的约束
xmlns:context="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
注解创建对象
4、开启注解的扫描
到包里面扫描、方法、属性上面是否有注解
<context:component-scan base-package="cn.itcast"></context:component-scan>------>指定包的注解全部扫描
<context:annotation-config/>------>只会扫描属性上的注解
开发的时候通常选择第一种,效果拔群
applicationContext.xml的代码如下
1、在创建对象的类上面使用注解实现
@Component(value="user")//相当于配置文件创建对象的<bean id="user" class="">
此时value中的user就等于id中的值测试类getbean使用的是value的user
不写value,只写字符串也可以实现
接下来我们来测试一下,测试代码如下:
测试结果如下
2、创建对象有四个注解
这三个注解是
(1)@Component
(2)@Controller//控制层
(3)@Service //业务层
(4)@Repository //修饰数据访问层
四个注解功能时一样的,都用来创建对象,存在是为了让标注类本身的用途清晰
一般分不清应该用哪个注解是,就用@Component,比如最基础的javabean类
3、用注解实现创建对象单实例还是多实例
在类上面加上注解@Scope(value="prototype"),value的值为singleton和prototype
那么在controller、service、dao三层结构中,应该怎么完成对象的注入呢?
以service和dao为例,我们来试验一下
注解创建属性
目的:创建service类,创建dao类,在service得到dao对象
注入属性第一个注解@Autowired,虽然可以实现注入,但是在逻辑上不会很清晰,并没有指定使用哪个对象,这种注解会称为自动注解/自动组装/自动装配
byName:根据引用对象的名称自动匹配
byType:根据引用对象的类型自动匹配
constructor:根据构造函数进行匹配
当然我们也能在自动注解的基础上指定注入的对象,以免造成注入对象之间的错误
@Qualifier(属性="属性值")//配合@Autowired使用
实现过程:
(1)创建dao对象
(2)创建service对象,在service类里面定义dao类型属性
实现效果如下
注入属性的第二种注解@Resource
@Resource(name="userDao")
/*这里面name属性写注解创建dao对象value值,此时name的值和注解Conponent就有
关系了,它能指定使用哪一个注解创建的属性,前提类名一致,这种逻辑上比较清晰,
而且开发的时候经常用到,这种注解称为手动注解*/
private UserDao userDao;