Spring入门初探
Spring简单理解
Spring是一种用来解耦合的框架,解决业务层和其它层之间的耦合关系过紧而导致的程序扩展性不强的问题。
Spring的核心思想就在于IOC和AOP。
说人话就是 控制反转 和 面向切面编程。
Spring IOC
IOC理解
首先说一下Spring IOC是个什么东西。
Spring IOC叫做控制反转,听起来相当玄乎。那么我们要搞清楚的是啥叫控制反转。
举个例子:
Java中产生对象的方式一般来说有三种:
1.new
2.简单工厂
3.Spring IOC的 getBeans()方法
其中,前两种方式来产生对象,都是主动自己的生产对象。而对于Spring IOC来说,对象由Spring IOC容器产生,我们要做的就是去容器中把需要的对象取出来就行了(一般来说,xml中的一个bean对应一个对象)。
所谓的反转就是在这里产生的,由产生转换为取对象,出现了动作上的反转,因此称为控制反转。
在漫长的演变史中,大家觉得控制反转这个词太难以理解了,因此,在经过两次关于Spring的会议中,将IOC改为DI,也就是常说的依赖注入。
也就是说,控制反转和依赖注入压根就是一码事。
所谓的依赖注入,就是将属性值注入给属性(俗称“赋值”),将属性注入给bean,将bean注入给容器。
当我们要使用对象的时候,就去IOC容器中取出来就完事了。
ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml");//获取IOC容器
obj = context.getBeans("id");//根据id值去IOC容器中那对象
obj.method();//正常的对象调用方法
IOC的注入方式
一般来说,IOC一共有四种注入方式。也有说三种的,第四种叫做自动装配注入,姑且认为它也算一种注入方式吧。
1.set注入
这种注入方式是Spring默认的注入方式。
<bean id = "***" class = "*****">
<property name = "****" value = "*****"></property>
</bean>
这种注入方式的底层实现其实就是利用反射机制来调用类中的set方法实现赋值操作。
新建对象实质上是调用类的无参数构造函数,因此,要用IOC容器装的对象必须保证有一个无参数的构造函数(由于构造函数会被重载,因此空参构造函数一定要明明白白的写出来!)
2.构造器注入
这种注入方式说白了就是通过调用带参数构造函数来注入
<constructor-arg value = "***" index/type/name = "****"></constructor>
默认来说,注入的value与构造函数参数列表中定义的顺序一致,不一致的话按照index(参数位置)/type(参数类型)/name(参数名字)绑定value值。
3.p命名空间
在xml文件的头部加上:
xmlns:p="http://springframework.org/schema/p"
使用方法:
<bean id="***" class = "***" p:参数名 = “***” p:参数名=“***” ...>
</bean>
注意:多个p参数之前要用空格隔开
4.自动装配注入
这种自动装配只适合ref类型,就是说,对象之间有依赖时才能够使用自动装配注入。
<bean id="***" class="***" autowire="byName">
</bean>
这个autowire就是自动装配的关键字,可选项还有:byType和constructor。
autowire:某类的ref属性 = 其他bean的id时,自动注入
byType:IOC容器中,只有唯一的类型满足时才可以使用
constructor:本质是byType
这个应该不算是一种注入方式,但是还是写一下吧。用的还是比较多。
5.用注解定义bean
顾名思义就是通过注解的方式将bean及属性值注入IOC容器中。
a.在xml中定义一个扫描器:
<context: component-scan base-package ="包名">
</context>
该扫描器会扫描该包,看是否有注解,若有相关注解,则将被注解修饰的类的对象纳入IOC容器。
b.在要纳入IOC容器的bean类头上加上注解,不同类型的方法上加上对应的注解。
注解 | 作用 |
---|---|
@component(“id值”) | 该组件为bean的对象 |
@Responsitory | 该组件为DAO的对象 |
@Service | 该组件为service的对象 |
@Controller | 该组件为controller的对象 |
IOC如何注入不同类型的值
IOC容器中的对象,会有很多不同的属性值,这些属性值也都可能从属于各种类型,比如String、int、set、list,或者可能是其他对象的引用。针对不同类型的属性值,IOC有不同的注入规则。
1.基本数据类型+String:name=??, value=??
2.引用类型:name=??,ref =“id”
3.集合类型(set、list、map、properties):各自有各自的标签,也可以混用
4.特殊字符
字符 | value属性 | value标签 |
---|---|---|
< | < | 1.<![CDATA[<]]>;2.同value属性的用法 |
> | > | 1.<![CDATA[>]]>;2.同value属性的用法 |
& | & | 1/<![CDATA[&]]>;2.同value属性的用法 |
注入值的时候,也有两种方式可以采用:value属性和value标签
<bean id = "***" class = "*****">
<property name = "****" value = "这就是value属性"></property>
</bean>
<bean id = "***" class = "*****">
<property>
<value>"这就是value标签">
</value>
</property>
</bean>
Spring AOP
AOP叫做面向切面编程。
个人肤浅的理解就是:将某一个在不同类中都会被多次使用的方法抽出来,包装起来成为一个独立的功能模块。哪个类需要在哪个位置用,就通过配置文件,将该模块切进去。
主要有三个基本概念:
切面:要执行的AOP方法
切入点:要切入的业务类方法
通知:AOP方法的一些分类(包括:前置通知、后置通知、环绕通知、异常通知、最终通知)
为了要实现Spring AOP,首先需要将必要的jar包导入:
aopalliance.jar
aspectjweaver.jar
注意:AOP的底层实现技术就是aspectJ,这也就是要导入aspectjweaver.jar的原因。
Spring AOP的实现方法一:接口
通过实现接口的方式来实现将一个普通类变为AOP类。
- 接口类型介绍:
通知类型 | 接口 | 需要重写的方法 |
---|---|---|
前置通知 | org.springframework.aop.MethodBeforeAdvice | before( ) |
后置通知 | org.springframework.aop.AfterReturningAdvice | AfterReturning( ) |
异常通知 | org.springframework.aop.ThrowsAdvice | 无 |
环绕通知 | org.aopalliance.intercept.MethodIntercepter | invoke( ) |
注意:异常通知中没有需要override的方法,但必须要实现:
void afterThrowing(Method method, object[] args, object[] target, Exception e)//最后一个参数为Throwable或其子类
2.实现步骤
a. 编写业务类和aop类
编写业务类即编写我们的切入点。
编写aop类就是根据需要的通知类型分别去实现上述的接口、重写方法,完事。
(是不是很简单)
那么问题来了,咋切入呢。
当然是通过配置啦
b.配置
(1)头部加上:
xmlns: aop = "http://www.springframework.org/schema/aop"
(2)将业务类和aop类加入Spring IOC
(咋加??)
正常类咋加就咋加(当然是配bean啦!)
(3)配置aop:
<aop:config>
#定义切入点,即业务类
<aop:pointcut expression = "业务类全类名1" or expression = "业务类全类名2" id = "...">
#定义aop类及 连接业务类和aop
<aop:advisor advice-ref = "aop类bean的id", point-ref="切入点的id" />
</aop:config>
Spring AOP的实现方法二:注解
注解这玩意儿,应该还是比较了解了。
(下一篇写写注解吧,自己也复习复习)
1.常规的还是先来总结一下实现aop要用的注解叭
通知类型 | 注解 |
---|---|
前置通知 | @Before |
后置通知 | @AfterReturning |
环绕通知 | @Around |
异常通知 | @AfterThrowing |
2.实现步骤
a.编写业务类和aop类
这个时候就不要实现接口啦,正正经经写个类就好了
b.配置
(1) 将业务类和aop类加入Spring IOC容器
业务类:类头上加@component,对于其中不同类型的业务方法再区分什么controller呀、service呀之类的。
aop类:类头上@Aspect,对于其中不同类型的通知方法再区分Before还是After等等。
(2)开启注解对AOP的支持
<aop: aspect-autoproxy></aop: aspect-autoproxy>
(当然,为了开启注解对IOC的使用,要定义个扫描器,扫描器就会将指定包里面的@component及另外三个修饰的类的对象增加到IOC容器中)
完成!