今日分享开始啦,请大家多多指教~
IOC创建对象的两种方式
1. 无参构造方式
sprirng使用无参构造的方式新建对象,然后使用set方法注入属性,表现为在bean.xml的property来对属性进行赋值。
如果实体类中没有set方法,property来对属性进行赋值。
2 有参构造方式
在实体类增加有参构造方法,(无参构造是默认含有的。)
修改bean.xml方法
回顾一下java的知识,在创建java对象时,无参构造函数是默认含有的,但是有参构造函数写了之后,默认的无参构造就会失效,这个时候要使用无参构造需要手动写一个无参构造函数。
spring配置
1 别名配置
spring别名的配置规则
和mybatis的有些类似,在mybatis中是这样使用的。
配置了别名之后,在java代码中就可以通过别名来获取对象实例了。
2 bean配置
这一个配置文件用java代码来解释就是
Hello hello = new Hello();
hello.setName(Spring);
3 多团队协作import
如果在团队开发中要使用别人写的xml文件,可以使用import的方式来实现,这样,就可以在自己的bean中使用别人bean的属性。
依赖注入
依赖注入作为Spring实现IOC的方式,允许大家使用多种方式来进行bean属性值的注入。
1 有参构造器注入
在4当中已经实现了构造器注入
2 set注入
要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型, 没有set方法 , 是 is .
创建实体类用于测试
Student.java
因为学生对象中含有对象Address
Address.java
常量注入(常用的数据类型,如inter,string,double等)
对象注入
在这里ref是引用。
数组注入
list注入
map注入
set注入
property
null注入
结果
3 使用命名空间注入
P命名空间注入 : 需要在头文件中假如约束文件
c 命名空间注入 : 需要在头文件中假如约束文件
4 Bean的作用域
Singleton单例
Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
Prototype
当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求时都会创建一个新的bean实例。
Request
当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。
<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
Session
当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。
Bean的装配与管理
在很多情况下,我们需要在一个类中使用另一个类对象,但是我们已经将对象的创建交给了Spring管理。
所以我们需要通过一些方式来对我们的类中的对象属性进行装配,也就是对象注入,其原理方式和属性值的注入类似。
1 通过ref来装配
我们现在有三个类
我们必须将三个类注入到SpringIOC容器中。
并将Cat和Dog装配到Peoson中才可以正常使用,就和属性值的注入类似。
实质就是将Cat和Dog实例从IOC中取出并赋值给Peoson类。
这样手动装配也很方便,但是又更加简便的方式来简化这一过程–>自动装配autowire。
我们可以使用xml配置 , 或者注解的方式来实现自动装配。
2 xml配置实现自动配置
2.1 byName
只需要通过这种简单的自动装配方式就可以实现之前的功能。它是根据bean的id来和set方法属性名来自动进行匹配的。
2.2 byType
用法一样,这个是通过类的类型来自动装配。因为是通过类型,所以同一类型的对象实例只能同时存在一个。
3 使用注解实现自动装配
jdk1.5开始支持注解,spring2.5开始全面支持注解。
第一步我们使用ref引用的方式来bean实例装配。
第二步我们使用autowire的方式来实现bean自动装配。
第三步将用注解的方式来实现自动装配。
使用注解方式需要增加一些配置。
在spring配置文件中引入context头文件。
开启属性注解支持!
3.1 Autowired
@Autowired是按类型自动转配的,不支持id匹配。
需要导入 spring-aop的包!(已经在mvc的jar包中导入)
使用方法:
实体类:
bean.xml
@Autowired默认是通过类型来匹配的,可以理解为byType的匹配规则
因为注解方式不是使用set的方法来进行注入,所以在实体类中可以不写set方法。
3.2 @Qualifier
@Autowired是根据类型自动装配的,加上@Qualififier则可以根据byName的方式自动装配
@Qualififier不能单独使用。
使用方法:
实体类:
bean.xml
通过这么一种方式,就可以实现和ref一样的功能。
它也可以写在set方法上。
@Autowired(required = false) //这个注解意思是允许参数为空,但是我测试默认他就允许为空,不知道它的意义在哪。
4 使用另一种注解的方式来实现自动配置
4.1 @Resource
@Resource如有指定的name属性,先按该属性进行byName方式查找装配;
其次再进行默认的byName方式进行装配;
如果以上都不成功,则按byType的方式自动装配。
实体类:
bean.xml
通过这样的方式,也可以实现ref的功能。
它和**@Autowired一样可以写在set方法**上。
5 @Autowired与@Resourse的异同
同样可以写在属性或者set方法上,配合属性使用可以实现ref的功能。
@Autowired属于spring规范,默认byType的方式匹配
@Resource(属于J2EE复返),默认通过byname的方式匹配。
注解开发
在spring中,虽然可以使用xml的方式来进行bean的注入,bean的装配,bean属性值的注入。但是实际开发用注解进行开发是真的香,而使用xml进行bean的管理和装配的方式将会逐渐摒弃。
1 准备工作
在完成通过注解的方式来对bean进行注入之后,也可以用注解的方式来实现属性的自动注入。
前置环境:
2 bean注入和属性值赋值
实体类:
可以在属性值上直接注入,但是有set方法时建议在set方法上注入。
通过@Value("")的方式直接注入属性值,功能和bean中的相同。
@Component注解和bean.xml文件中的bean标签作用一样,意思是将这个类交由spring容器管理。
通过这种方式将实体类注入IOC容器之后不再需要在bean.xml中对实体类进行注入。
3 Component衍生注解
我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
@Component三个衍生注解
为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。
**@Controller:**web层
**@Service:**service层
**@Repository:**dao层
写上这些注解,就相当于将这个类交给Spring管理装配了!
4 bean的自动装配
在之前的博客有写到在一个bean中使用另一个bean。
而通过这么一种方式,实现了bean的装配。结合之前的内容,我们将可以完全摒弃xml配置文件的方式来对bean进行管理和注入。
注解方式,快捷而优雅
这样配合使用就完成了所有在bean.xml中的类和属性注入的所有功能。
5 作用域 @scope
singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收。
6 小结
使用全注解的方式是主流的一种只用方式,在后续的springboo中更是常见使用。但是了解xml的方式有助于我们使用和理解框架的逐步演进。
xml方式
注解方式
依赖注入只是IOC的一种实现,我们希望将对象的创建和管理交给Spring容器管理,这会让我们在管理类的时候不再需要进行复杂的代码更改,而用注入的方式一次性改变
例如:
private SqlService sqlService = new MySqlServiceImpl()
如果我们需要更改实现类,我们需要重新new一个对象
private SqlService sqlService = new OracleServiceImpl()
但是依赖注入的方式不同,它是这样实现的
这样节省了我们出创建一个新对象的额外开销。
代理模式
AOP面向切面编程的底层思想就是代理模式,理解代理模式对理解AOP模式很有帮助。
代理模式分为:
静态代理
动态代理
用UML图来简单描述一下
1 静态代理
静态代理角色分析
抽象角色 : 一般使用接口或者抽象类来实现
真实角色 : 被代理的角色
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .
客户 : 使用代理角色来进行一些操作 .
静态代理实例一:
抽象角色Rent
真实角色Host
客户client
**理解:**代理模式中,真实角色和代理角色共同实现租房这一抽象接口,真正拥有租房权限的是真实角色,因为代理角色找到了真实角色,真实角色将租房这一权限给代理。
**优点:**代理角色除了代理了租房这一功能还可以提供其他的一些附加功能,比如签合同,看房等,这是真实角色不想做的事情,但是却不会影响他本身的租房功能。
静态代理实例二:
抽象接口UserService
真实角色UserServiceImpl
代理角色UserServiceImplProxy
客户端
**理解:**和之前的静态代理案例一一样,通过代理角色的方式,在实现真实角色功能的基础上,不影响地增加一些代理功能。
这也是AOP底层的实现机制
2 动态代理
就和在mybatis时做分页一样,当分页的类型多的时候,我们不希望为每一种类型都增加一个分页类,这个时候我们使用泛型的方式来实现不同类型数据的返回匹配。
动态代理的角色和静态代理的一样 .
动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
基于接口的动态代理----JDK动态代理
基于类的动态代理–cglib
现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist
JDK的动态代理需要了解两个类
核心 : InvocationHandler 和 Proxy 。
通过这样的方式,我们就可以动态的代理Rent这一类的对象了。
除了代理这一类的方法,有时候我们希望能够实现所有对象的代理,这个时候我们可以把Rent改为Object类型,这样就可以代理所有的对象类型了。
使用方法:
3 小结
就和工具类一样,动态代理可以很方便的动态完成一些有需求变更和频繁使用的工作。
AOP
AOP作为spring的两大核心之一,即面向切面编程,它的底层实现是代理模式,横向的方式来对现有的功能进行加强,使业务逻辑和功能代码更好的脱耦合。
1 Aop在Spring中的作用
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
目标(Target):被通知对象。
代理(Proxy):向目标对象应用通知之后创建的对象。
切入点(PointCut):切面通知 执行的 “地点”的定义。
连接点(JointPoint):与切入点匹配的执行点。
SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:
2 AOP的使用
环境:需要导入jar包
第一种方式
通过继承已有的方法,然后通过AOP配置文件来设置切入面和执行环绕的方式
抽象接口UserService
真实角色(房东)
通过这样的一个方式,我们实现了之前和动态代理类似的功能。
第二种方式
有的时候它提供的代理方法可能不是很适配我们的功能需求,我们希望通过自定义代理类的方式来实现代理功能,而不是通过它现有的方法。
自定义的代理类Proxy
第三种方式
通过注解的方式实现
bean.xml
整合mybatis
mybatis实现对数据库操作的高效管理,而spring用一种新的方式实现对对象的创建和使用。
整合mybatis就是将mybatis的数据操纵和spring的控制反转结合起来。
导入相关jar包
改造mybatis
原本我们的mybatis是有User实体类和UserMapper接口和UserMapper.xml,还有mybatis-config.xml。
主要就是改造mybatis-config文件,我们需要把一些mybatis连接数据库的操作转移到spring中一起操作。
新建一个spring-config.xml文件
在这个文件中,我们将Sqlsession的获取,对数据库的连接,对mybatis的一些配置整合在了一起。
操作sqlsession
在测试类中用getbean()方式来获取session
通过一个UserMapperImpl实现类将session注入。(规范)
官方文档的规范是使用第二种方式来进行实现的,同时这也更符合spring依赖注入的思想。
优化
通过导入的方式将配置部分和普通的bean注入分离
将sqlsession获取进一步简化。
mybatis-spring1.2.3版以上才可以使用 .
继承SqlSessionDaoSupport, 直接利用 getSqlSession() 获得Sqlsession , 在bean管理就直接为UserMapperIml注入SqlSessionFactory(原来是注入sqlSession) 。
将sqlSessionFactory注入即可。
将UserMapperImpl分离成service层
有一个UserMapper.xml后再实现一个UserMapperImpl的话逻辑会有些乱,可以将UserMapperImpl分离出来,单独建一个service层。将session的获取在这一个层次进行。
注入session类型
继承SqlSessionDaoSupport类
获取sesission的方式进一步简化:
当我们的获取Session的操作更多的时候,我们希望以一种更加高效和更加便于管理的方式去获取session。
spring框架提供了一个自动扫描MapperScannerConfigurer的操作,它可以通过设置这个类的属性和自动扫描指定包来自动的将我们的session注入到包名下的所有mapper中。
我们可以直接获取mapper去操作,而将session的获取交给spring封装。
使用方法:
配置文件:
它需要手动地设置两个属性来为指定包名注入session.
调用
private UserMapper userMapper;
直接调用即可使用。
事务
对于事务的更详细地解释在我的另一篇博客中有显示
事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!
事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性。
事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。
事务四个属性ACID
1.原子性(atomicity)
事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用。
2.一致性(consistency)
一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中。
3.隔离性(isolation)
可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
4.持久性(durability)
事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中。
事务的作用
当我们在操纵数据时,我们在同一个方法执行增删改查操作,我们希望当我们一个操作发生错误时,这个方法内的所有操作都失效。而spring的提供的很好的这个管理功能,叫做事务管理。
事务的使用
引入aop和tx头文件
定义为一个事务管理器,为它绑定数据源
详细配置事务的通知规则
使用aop织入
今日份分享已结束,请大家多多包涵和指点!