Spring总结
一、核心思想:
1.控制反转IOC:
当使用spring时我们就不需要关心通过何种方式实例化一个对象,spring通过控制反转机制自动为我们实例化一个对象。
2.依赖注入DI:
Spring使用java Bean对象的Set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。
3.面向切面AOP:
在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。
二、实例化容器:
BeanFactory和ApplicationContext就是spring框架的两个IOC容器,ApplicationnContext不但包含了BeanFactory的作用,同时还进行更多的扩展。
实例化Spring IOC容器的两种方法:
1.方法1:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“spring配置文件路径”}); |
2.方法2:
Resource res = new FileSystemResource(“spring配置文件”); BeanFactory factory = new XMLBeanFactory(res); |
三、配置文件:
1.多配置文件:
当Spring需要管理和配置的东西比较时,可以按照功能模块将spring配置文件分开配置,例如:DAO层配置到一个spring-dao.xml配置文件中,Service层配置到spring-service.xml文件中,Struts的action配置到spring-action.xml文件中,然后通过下面两种办法将这些分散的配置文件组合起来:
方法1:
通过<import>元素将要引入的spring其他配置文件引入:
<beans> <import resource=”spring-dao.xml”/> <import resource=”spring-service.xml”/> <import resource=”spring-action.xml”/> …… <bean> </bean> …… </beans> |
方法2:
获取ApplicationContext对象时将所有的spring配置文件通过数组传递进去,也可以使用通配符如spring-*.xml方式。
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“spring配置文件路径”}); |
对于JavaEE工程,在web.xml文件中指定spring配置文件时可以指定多个,中间有逗号“,”分隔,也可以使用通配符方式。
2.配置规则:
1) 一个Bean可以通过一个id属性惟一指定和引用,如果spring配置文件中有两个以上相同的id时,spring会报错id冲突。
2) 一个Bean也可以通过一个name属性来引用和指定,如果spring配置文件中有两个以上相同name的Bean,则spring通过name引用时,运行时后面的会自动覆盖前面相同name的bean引用,而不会报错。
四、依赖注入:
1.依赖注入三种方式:
1) 构造器注入:
<bean id=”……” class=”……”> <constructor-arg>构造函数需要的参数1</constructor-arg> <constructor-arg>构造函数需要的参数2</constructor-arg> …… </bean> |
2) 属性的Setter注入:
使用属性的setter注入方式时,所注入的属性必须提供setter和getter方法;
<bean id=”……” class=”……”> <property name=”属性1” value=”……”/> <property name=”属性2” value=”……”/> …… </bean> |
3) Field字段注入:
在java中的字段上或者setter方法上通过使用注解方式进行spring的依赖注入。
@Resource private UserDao dao;
@Resource public void setUserDao(UserDao dao){ this.dao = dao; } |
2.注入依赖bean:
Spring中为一个bean注入其依赖的另一个bean时,通过使用ref来注入另一个bean。
<beans> <bean id=”bean1” class=”……”> <property name=”属性1” value=”……”/> …… </bean> <bean id=”bean2” class=”……”> <property name=”bean1” ref=”bean1”/> …… </bean> </beans> |
3.集合注入:
1) Set集合注入:
<bean id=”……” class=”……”> <set> <value>value1</value> <value>value2</value> …… </set> </bean> |
2) List集合注入:
<bean id=”……” class=”……”> <list> <value>value1</value> <value>value2</value> …… </list> </bean> |
3) Map集合注入:
<bean id=”……” class=”……”> <map> <entry key=”key1” value=”value1”> <entry key=”key2” value=”value2”> …… </map> </bean> |
4) Properties集合注入:
<bean id=”……” class=”……”> <props> <prop key=”key1”>value1</prop> <prop key=”key2”>value2</prop> …… </props> </bean> |
五、注解:
Java注解(Annotation)是通过在java源文件上添加标记字段,然后通过反射的反射在编译或者运行时获取这些标记字段以及其标记目标,然后进行相应处理的方法。
1.JDK内置注解:
JDK内置了三个注解:
@Override:声明某个方法被重写。
@Deprectated:声明某个方法过时,不推荐使用。
@SuppressWarning({“unchecked”,…….}):告诉编译器对于那些警告信息忽略。
2.自定义Java注解:
Java注解就是一种特殊的接口,如下:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.CLASS) public @interface TestAnnotation{ String value() default “”; } |
相关说明如下:
序号 |
字段名称 |
说明 |
1 |
@Retention |
告诉编译器如何处理注解,即注解运行在什么时刻。 RetentionPolicy是个枚举类型,有以下三种状态值: 1).SOURCE:该注解存储在源文件中,编译过后即废弃。 2).CLASS:该注解存储在class文件中,是其缺省的值。 3).RUNTIME:该注解存储在class文件中,并且有Java虚拟机读入解析,该类型非常重要,可以使用反射机制获取注解相关信息,可以进行程序分析处理。 |
2 |
@Target |
指定注解的目标使用对象。 ElementType也是个枚举类型,有以下几种状态值: 1).TYPE:该注解适用于class,interface,enum等类级别的目标对象。 2).FIELD:该注解适用于类中字段级别的目标对象。 3).METHOD:该注解适用于类中方法级别的目标对象。 4).PARAMETER:该注解适用于方法参数级别的目标对象。 5).CONSTRUCTOR:该注解适用于类构造方法。 6).LOCAL_VARIABLE:该注解适用于局部变量。 7).ANNOTATION_TYPE:该注解适用于annotation对象。 8).PACKAGE:该注解适用于package对象。 |
1) 若要想自定义的注解可以被继承,则需要在自定义注解类上加上“@Inherited”注解。
2) java的注解实际上是自动继承了java.lang.annotation.Annotation接口,因此在自定义注解时不能继承其他的注解或者接口。
3) 注解里面只能声明属性,不能声明方法,声明属性的方式比较特殊:
语法格式为:
数据类型 属性() default 默认值(默认值是可选的);
如:Stringvalue();
使用时,“注解对象(属性=属性值)”为注解指定属性值,通过“注解对象.属性;”就可以得到注解属性的值。
3.基于注解的Spring配置:
1) 使用spring注解方式,必须加入spring注解方式所依赖的jar包:common-annotation.jar。
2) 使用注解方式时,必须在spring配置文件的schema中添加注解的命名空间如下:
xmlns:context=”http://www.springframework.org/schema/context” http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd |
3) 在spring配置文件中注册注解处理器:在spring配置文件中<bean>元素之前添加:
<context:annotation-config> |
4) Spring 2.5使用四个注解按功能来进行对bean的配置:
a) @Component:泛指组件,对于一般不好归类的java Bean使用。
b) @Service:用于标注配置业务层(service层)组件。
c) @Controller:用于标注配置控制层的组件(如Struts中的action)。
d) @Repository:用于标注配置数据访问层组件,即一般的DAO层Bean对象。
注意:对于使用spring注解方式配置的bean对象,bean引用时默认名称为被注解名称的首字母小写形式,也可以指定名称,如:@Service(“userDao“)。
六、自动装配:
自动装配的是指不用手动显式配置java Bean之间依赖关系,而是让spring依据某种规则自动将合适的对象注入到目标对象的过程。Spring中常用@Autowire和@Resource来进行自动装配。
1.@Autowire:默认是按照对象的数据类型进行自动装配的,如
@Autowire private UserDao userDao; |
spring框架在运行时会自动将类型为UserDao的对象注入进来。
2.@Resource:默认是按照名称或者Id进行自动装配的,只有当找不到匹配的名称或者Id时才按类型进行装配,如:
@Resource(name=”userDao”) private UsreDao userDao; |
spring框架在运行时会将配置名称或者id为“userDao”的对象注入进来。
七、自动扫描:
自动扫描很简单,只需要在spring的配置文件中添加如:
<context:component-scan base-package=“要自动扫描的包名“> |
Spring在运行时就可以对指定的包中所有添加了Spring注解的bean自动扫描,注入,装配和初始化。
八、面向切面编程AOP:
Spring面向切面编程的的底层实现原理是动态代理;
1.概念:
序号 |
名称 |
说明 |
1 |
横切关注点 |
在java对象中,可以在具有类似共同处理逻辑的位置加入如权限验证、事物处理、日志记录等处理逻辑的对象称为横切关注点。 |
2 |
切面(Aspect) |
将横切关注点抽象就形成切面 |
3 |
连接点(Joinpoint) |
被拦截到的点,在Spring中指方法,因为spring只支持方法类型的连接点,即被拦截的方法。 |
4 |
切入点(Pointcut) |
指对连接点进行拦截的定义,是连接点的集合,即一系列被拦截方法的集合。 |
5 |
通知(Advice) |
指拦截到连接点之后要做的事情,即拦截之后的逻辑处理。通常的权限验证、事物处理、日志记录等操作就是在通知中定义和完成的。 |
6 |
目标对象(Target) |
代理的目标对象,即被拦截的对象。 |
7 |
织入(Weave) |
指将切面应用到目标对象,并导致代理对象创建的过程。 |
8 |
引入(Introduction) |
在不修改代码的前提下,引入可以在运行期为类动态的添加一些方法和字段。 |
2.Spring中面向切面编程的依赖包:
lib/aspectj/aspectjweaver.jar
lib/aspectj/aspectjrt.jar
lib/cglib/cglib-nodep-2.1-3.jar
3.Spring中的配置:
在spring中使用面向切面编程(AOP)时,需要在spring配置文件中引入aop的命名空间,即添加如下的配置:
xmlns:aop=”http://www.springframework.org/schema/aop” “http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd” |
若要使用注解方式的aop,需要在spring配置文件中添加如下的对象注解方式aop的支持:
<aop:aspectj-autoProxy/> |
4.基于注解的面向切面编程:
1) 在spring配置文件中加入对注解方法的aop支持。
2) 定义切面:和创建普通类类似,在类前加上”@Aspect”注解,表明该类是一个切面。
3) 在切面中加入切入点:切入点就是被拦截对象方法的集合,通常切入点定义在切面中某个对切入点进行处理的方法上。使用”@Pointcut”注解,语法如下:
@Pointcut(“execution(* com.test.service..*.*(..))”) public void anyMethod(){//方法名为切入点名 切入点处理 } |
参数详解:
l 第一个”*”:表示被拦截的方法是任意的返回类型。
l com.test.service:这里是举一个简单的例子,表示要被拦截的包名,即被拦截的包。
l 被拦截包名后面的两个”..”:表示被拦截包下面的子包也递归进行拦截,即被拦截的子包。
l ”..”之后的”*”:表示被拦截包及其子包下面的所有类,即被拦截的类。
l 最后一个”*”:表示被拦截类中的所有方法,即被拦截的方法。
l ”(..)”:表示被拦截的方法接收任意的参数,即被拦截的参数。
注意:切入点定义语法可以支持通配符,但是一定要严格遵循语法规则。如:@Pointcut(“execution(*com.test.service..*.add*(..))”)
表示对com.test.service包及其子包下所有的类中以”add”开头的方法进行拦截。
4) 在切面中添加通知:
”@Before”注解:声明前置通知。
“@AfterRutruning”注解:声明后置通知。
“@After”注解:声明最终通知。
“@AfterThrowing”注解:声明例外通知。
“@Around”注解:声明环绕通知。
5.基于XML的面向切面编程:
1) 定义切面类,在切面类中添加通知。
2) 将切面类想普通java类一样在spring配置文件中配置。
3) 在spring配置文件中添加AOP配置如下:
<aop:config> <!--配置切面--> <aop:aspect id=”切面id” ref=”spring配置文件中切面类的id”> <!--配置切入点--> <aop:pointcut id=”切入点id” expression=”execution(* com.test.service..*.*(..))”/> <!--配置通知--> <aop:before pointcut-ref=”切入点id” method=”切面类中相应的处理方法”/> <aop:after ……/> …… </aop:aspect> </aop:config> |
九、事务处理:
1.基于注解的事务管理:
1) 在spring配置文件中添加事务管理的命名空间如下:
xmlns:ts=http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd |
2) 在spring配置文件中配置事务管理器如下:
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”spring中配置的数据源bean的id”/> </bean> |
3) 在spring配置文件中添加支持注解方式的事务配置项如下:
<tx:annotation-driventransaction-managertx:annotation-driventransaction-manager=”txManager(spring中配置的事务管理器bean的id)”/> |
4) 使用基于注解的事务管理:
在Spring所管理的JavaEE工程中,需要使用事务的业务逻辑地方加上“@Transactional”注解。 |
2.基于XML的事务管理:
1) 在spring配置文件中配置事务管理器如下:
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”spring中配置的数据源bean的id”/> </bean> |
2) 在spring配置文件中添加事物管理的切面如下:
<aop:config> <!--配置事务切入点--> <aop:pointcut id=”transactionPointcut” Expression=”execution(* com.test.service..*.*(..))”/> <!--配置事务通知--> <aop:advisor advice-ref=”txAdvice” pointcut-ref=”transactionPointcut”/> </aop:config> |
3) 在spring配置文件中为事务通知添加事物处理特性如下:
<tx:advice id=”txAdvice” transactionManager=”txManager”> <tx:attributes> <!--这里举例将以get开头的查询方法设置为只读,不支持事务--> <tx:method name=”get*” read-only=”true” propagation=”NOT_SUPPORTED”/> <!--其他的方法设置为spring默认的事物行为--> <tx:method name=”*”/> </tx:attributes> </tx:advice> |
十、参考资料:
http://www.cnblogs.com/ITtangtang/p/3978349.html
http://blog.csdn.net/jaryle/article/details/51219062
http://blog.csdn.net/zjx86320/article/details/46683455
http://blog.csdn.net/chjttony/article/details/6026079
http://blog.csdn.net/chjttony/article/details/6042127