一、bean注入方式
1、设值注入
2、构造注入
二、bean配置项
Id | 标识符 |
Class | 指定类 |
Scope | 作用域 |
Constructor arguments | 构造器参数 |
Properties | 自身属性 |
Aotowiring mode | 自动装配模式 |
Lazy-initialization mode | 懒加载模式 |
Initialization/destruction method | 初始化/销毁方法 |
Scope
- singleton:单例,一个bean容器只存在一份
- prototype:每次请求创建新的实例,destroy无效
- request:每次http请求创建一个实例且仅在当前request有效
- session:同上,
- global session:基于portle的web中有效(portle中定义了global session),如果是在web中,同session
三、bean生命周期
1、初始化
- 实现org.springframework.beans.factory.InitializingBean接口,覆盖afterPropetiesSet方法
- 配置init-method
2、销毁
- 实现org.springframework.beans.factory.DisposableBean接口,覆盖destory方法;
- 配置destory-method
配置有全局配置,bean中配置。当三种方法都存在时,全局配置不起作用。其他两种都会执行,且实现接口方法先于bean中配置执行
四、bean装配
1、Aware接口
- ApplicationContextAware :为实现此接口的bean提供上下文信息;
- BeanNameAware:提供bean在工厂中的id,提供了回调自身的能力
- ApplicationEventPublisherAware:bean事件发布
- BeanClassLoaderAware:bean加载容器
- BeanFactoryAware:获取beanfactory
可以先通过BeanNameAware接口得到beanName,再通过ApplicationContextAware接口的getbean获取该bean
2、bean的自动装配(Autowiring)
- No:不做任何操作
- byname:根据属性名自动装配,(根据set***方法的后面名字首字母小写匹配bean配置中id的)
- byType:根据属性自动装配。如果存在多个会抛出异常,不存在什么事都不会发生
- Constuctor:与byType方式类似,不同之处在于它应用于构造参数。
自动装配意义在于不需要在手动注入了 ,使配置更加简洁方便。在xml的【beans】中配置。
3、bean注解
- @Component 是一个通用注解,可用于任何bean,一般用于注册bean并指定一个id
- @Repository 通常用于注解DAO类,即持久层
- @Service 通常用于注解Service类,即持久层
- @Controller 通常用于Controller类,即控制层
- 记得加上<context:component-scan>
参考资料:spring常用注解
元注解:注解的注解,可以将多条注解自定义为一个注解
参考资料:Spring4.0系列4-Meta Annotation(元注解)
bean的自动检和注册:
Spring可以将上面四个注解的bean自动注册到容器(ApplicationContext)中,都有个name属性可以显示的设值bean的id,在xml中需要配置自动注册路径
bean的名称是由BeanNameGenerrator生成的,要自定义命名策略可以实现该接口并一定要包含一个无参构造器,并在<context:component-scan>;的name-generator中配置使用。
参考资料:Spring <context:annotation-config/> 解说
Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
自动注册可以通过<context:component-scan>的属性配置要注册的文件和要排除的文件;
自动注册的bean作用域默认是:singleton,可以@Scope指定,也可以使用自定义的scope策略,要实现ScopeMetadataResolver接口,并类似上面自定义命名规则的当时注册
可以使用scoped-proxy属性指定代理。三个可选值:no,interfaces,targetClass
@Required注解:适用于bean方法的setter方法,表示当被注解的属性在bean被装配时必须被设置,否则会抛出BeanInitializationException异常
@Autowired注解:可用于构造器、方法或成员变量,可以用此注解替代上面提到的Autowiring自动装配不用再写太多配置也不用再写set方法,方便快捷;如果找不到合适的bean将会抛出异常,可以通过required=false来避免。
@inject等效@AutoWiried @Named 等效Component @Named还可根据name注入字段
常见使用:
@AutoWired经常用来注解哪些众所周知的接口,来直接获取这些接口
@Autowired也可以通过添加注解给一些数组的字段或方法,来获取applicationContext中所有特定类型的bean
注意:@Autowired由Spring的BeanPostProcessor处理的,不能在 自己的BeanPostProcessor或BeanFactoryPosrProcessor类型应用这些注解,这些类型必须通过XML或者Spring的@Bean注解来实现;
@Order注解可以实现类的有序加载,其value越小越先被加载,针对list数组有效,对map数组无效。
@Qualifier当用@Autowiried自动装配时,是根据属性类型来装配的,可能有多个bean实例,可以用此注释来指定是哪一个bean实例。否则会报错。
参考资料:Spring @Qualifier 注释
@Resouce相当于@Autowiried加上@Qualifier的功能,某属性有多个bean时大多使用此注解,有两个参数name、type。有name时会按照byName进行装配
有type时会按照byType进行装配,两者都有时按照name和type查找。两者都没有时按照属性名利用反射机制装配。
@Bean常与@Configuration配合使用,@Congfiguration相当于<beans>,注解在类上表示一个注解类,@Bean相当于<bean>,注解在方法上,返回一个bean,不指定name,默认为方法名。默认是单例的
使用bean时也要加上<context:component-scan>扫面@bean注解的类的包
参考资料:Spring中基于Java的配置@Configuration和@Bean用法
在xml中<context:property-placeholder location="****.properties"/>用来加载资源文件。之后在xml中可以用${}引用,常见于数据库的配置信息
用注解的实现方式为@ImportResource("路径")@Value引用。
使用properties文件的方法:
在properties文件中写好键值对,如:name=tom
在xml中配置引入properties文件。<context:property-placeholder location="properties文件路径"/>
在java类上引入资源:@ImportSource("xml路径"),在字段上注解@Value("${name}")便可让字段获取tom值了
4、Spring AOP
1、AOP相关概念:
-
切面(Aspect):一个关注点的切面化,这个关注点可能会横切多个对象
-
连接点(Joinpoint):程序执行过程中的某个特定的点
-
通知(Advice):在切面某个连接点上执行的动作
-
切入点(Pointcut):匹配连接点的点,在AOP中通知和一个切入点关联
-
引入(Introduction):在不修改类代码的前提下,为类添加新的方法和属性
-
目标对象(Target Object):被一个或多个切面所通知的对象
-
AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)
-
织入(weaving):把切面链接到其他的应用或者对象上,并创建一个被通知的对象,分为:编译时织、类加载时织入、执行时织入
2、Advice类型
-
前置通知(Before advice):在某连接点(join point)之前执行的通知,但不能阻止连接点的执行(除非抛出异常)
-
返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知
-
抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知
-
后通知(After (final)advice)当某连接点退出时执行的通知(不论是正常返回还是异常退出)
-
环绕通知(Around Advice):包围一个连接点的通知,环绕通知(Around advice)的方法第一个参数必须是ProceedingJoinPoint,调用他的proceed()方法;
Spring所有切面和通知器都必须放在一个<aop:config>可以配置多个,每一个<aop:config>可以包含pointcut,advisor和aspect元素,必须按照这个顺序进行声明
3、pointcut
*:匹配任何数量字符;
..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。
参考资料:切入点表达式的配置
4、advisors
充当Advice和Pointcut的适配器,将pointcut和advice结合起来
5、引入(Introductions)
简介允许一个切面声明一个实现指定接口的通知对象,并且提供了一个接口实现类来代表这些对象。简单点说就是将原有的一个bean伪装成一个我们自己的类,调用该bean时会调用我们伪装的类。
5、spring AOP API
Pointcut通过API实现之一:NameMatchMethodPoint,根据方法名称进行匹配,成员变量:mappedNames里,有匹配的方法名集合
<bean id="***" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames">
<list>
<value>se*<!-- 方法名 --></value>
</list>
</property>
</bean>
before advice:实现接口。MethodBeforeAdvice
Throw Advice :类似,找接口
After Returning advice :实现org.springframework.aop.AfterReturningAdvice接口
around advice:实现MethodInterceptor接口
6、spring对aspectj的支持
1、@AspectJ切面使用@Aspect注解配置。拥有@Aspect的任何bean将被spring自动识别并应用
2、用@Aspect注解的类可以有方法和字段,他们也可能包括切入点、通知和引入声明
3、@Aspect注解是不能够通过类路径自动检测和发现的,所以需要配合@Conponent注释或者在xml中配置bean
4、一个类中的@Aspect注解标志它为一个切面,并且将自己从自动代理中排除
5、一个切点通过一个普通的方法定义来提供,并且切入点表达式使用@Pointcut注解,方法返回类型必须为void
7、spring事务管理
1、主要包括3个接口:
- PlatformTransactionManager事务管理器
- TransactionDefinition事务定义信息(隔离、传播、超时、只读)
- TransactionStatus事务具体运行状态
spring为不同的持久化框架实现了不同的PlatformTransactionManage接口
脏读:一个事务读到了另一个事务还没有提交的数据。如果数据被回滚,则独到的数据是无效的
不可重复读:在同一事物中,多次读取统一数据返回的结果有所不同
幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中第一个事务就会发现有些原来没有的数据。
隔离级别:
DEFAULT:使用后端数据库默认的隔离级别
READ_UNCOMMITED :允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读
READ_COMMITTED :允许并发事务已经提交后读取。可防止脏读、但幻读和不可重复读仍可发生
REPEATABLE_READ :对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生。
SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这是所有的隔离级别中最慢的,他是典型的通过完全锁定在事务中涉及的数据来完成的
事务传播行为:
PROPERGATION_REQUIRED:支持当前事务,如果不存在则创建一个
PROPERGATON_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPERGATION_MANDATORY:支持当前事务,如果不存在,抛出异常
PROPERGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务
PROPERGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务
PROPERGATION_NEVER:以非事务方式运行,如果存在事务,抛出异常
PROPERGATION_NESTED:如果当前事务存在,嵌套当前事务执行
2、spring支持两种事务管理:
---编程式事务管理
- 在实际应用中很少使用
- 通过TransactionTemplate手动管理事务
---使用XML配置声明式事务
- 开发中推荐使用
- spring的声明式事务是通过AOP实现的
3、编程式事务管理的实现(很少使用):
- 在要管理的类中使用TransactionTemplate,执行excute方法,在方法内构造一个TransactionCallbackWithoutResult()内部函数,覆盖 doInTransactionWithoutResult()方法
- TransactionTemplate依赖DataSourceTransactionManager
- DataSourceTransactionManager依赖DataSource构造
4、声明式事务管理:
- 需要的类为:org.springframework.transaction.interceptor.TransactionProxyFactoryBean;
<!-- 配置业务层代理 -->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置目标对象 -->
<property name="target" ref="accountService"/>
<pre name="code" class="html"> <!-- 配置事务管理 -->
<property name="transactionManager" ref="transactionManager"/> <!-- 配置事务属性 -->
<property name="transactionAttributes"> <props>
<prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> prop的取值有:
- PROPAGATION :事务的传播行为
- ISOLATON ::事务的隔离级别
- readOnly :只读(不可修改)
- -Exception:发生哪些异常回滚事务
- +Exception :发生哪些异常不回滚
5、基于Aspectj的xml方式配置事务管理(经常使用):
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务通知(事务的增强)
transaction-manager指向事务管理器
method配置需要假如事务的方法名并可以陪配置相关属性
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(* com.transaction.demo3.AccountService+.*(..))" id="pointcut1"/>
<!-- 装配切点和通知 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
6、基于注解的事务管理方式(经常使用)
也需要配置事务管理器
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在所需要假如事务的方法的类上加上@Transactional即可,并在@Transactional中可以配置事务相关属性;
8、SpringMVC
1、springMVC配置
pom.xml中配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>imooc-arthur</groupId>
<artifactId>spring-mvc-study</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<commons-lang.version>2.6</commons-lang.version>
<slf4j.version>1.7.6</slf4j.version>
<spring.version>4.1.3.RELEASE</spring.version>
<jackson.version>2.5.4</jackson.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.2.v20140723</version>
</plugin>
</plugins>
</build>
</project>
web.xml中:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Study</display-name>
<!-- Spring应用上下文, 理解层次化的ApplicationContext -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- DispatcherServlet, Spring MVC的核心 -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- DispatcherServlet对应的上下文配置, 默认为/WEB-INF/$servlet-name$-servlet.xml
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<!-- mvc-dispatcher拦截所有的请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
dispatcher-servlet.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 本配置文件是工名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置 -->
<!-- 启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required
@Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 -->
<context:annotation-config />
<!-- DispatcherServlet上下文, 只管理@Controller类型的bean, 忽略其他型的bean, 如@Service -->
<context:component-scan base-package="com.imooc.mvcdemo">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- HandlerMapping, 无需配置, Spring MVC可以默认启动。 DefaultAnnotationHandlerMapping
annotation-driven HandlerMapping -->
<!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
<mvc:annotation-driven />
<!-- 静态资源处理, css, js, imgs -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsps/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
applicationContext.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config />
<!-- @Controller已经在dispatcher-servlet.xml中配置过了。排除它 -->
<context:component-scan base-package="com.imooc.mvcdemo">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>
2、通过@RequestParam和@PathVariable两个标记可以获取到URL中传递的参数
3、Spring单文件上传
需要在dispatcher-servlet.xml中配置:
<!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="209715200" />
<property name="defaultEncoding" value="UTF-8" />
<property name="resolveLazily" value="true" />
</bean>
pom.xml中配置
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
并在文件上传的form中指定enctype="multipart/form-data"
4、处理JSON
需要在dispatcher-servlet.xml中配置:
<!-- 配置ViewResolver。 可以用多个ViewResolver。 使用order属性排序。 InternalResourceViewResolver放在最后。 -->
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="htm" value="text/html" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
引入依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
@Controller上的格式:
//两者都可以返回json数据
@RequestMapping(value="/{courseId}",method=RequestMethod.GET)
public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
return courseService.getCoursebyId(courseId);
}
@RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
public ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
Course course = courseService.getCoursebyId(courseId);
return new ResponseEntity<Course>(course, HttpStatus.OK);
}