spring4.x
2018-01-31 14:41:18 102 举报
AI智能生成
登录查看完整内容
spring 相关的知识
作者其他创作
大纲/内容
spring4.x
4 IoC容器概述
IoC概述
IoC控制反转:某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定
IoC的类型:构造函数注入:属性注入:接口注入:把调用类的所有依赖注入方法抽取到一个接口中,调用类通过实现接口的方法完成注入。
资源访问利器
BeanFactory和ApplicationContext
Bean的生命周期
二,ApplicationContext中Bean生命周期的完整过程:1,BeanFactoryPostProcessor#postProcessBeanFactory()对工厂定义信息进行后处理2,调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()3,实例化4,bean实例化之后,调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()5,Bean设置属性信息前,调用InstantiationAwareBeanPostProcessor#postProcessPropertyValues()6,调用Bean的属性设置方法设置属性值7,调用BeanNameAware#setBeanName()接口方法,将配置文件中该Bean对应的名称设置到Bean中8,调用BeanFactoryAware#setBeanFactory(),将BeanFactory容器实例设置到Bean中9,调用ApplicationContextAware的setApplicationContext()方法10,调用BeanPostProcessor的postProcessBeforeInitialization()方法11,调用InitializingBean的afterPropertiesSet()方法12,通过init-method属性配置的初始化方法13,调用BeanPostProcessor的postProcessAfterInitialization()方法14,如果Bean的作用范围为scope=\"prototype\",将Bean返回给调用者,调用者负责管理Bean的后续生命周期,Spring不在管理这个Bean的声明周期15,如果Bean的作用范围为scope=\"singleton\",则将Bean放入到Spring IoC容器的缓存池,并将Bean引用返回给调用者,Spring继续管理这些Bean的生命周期16,对于15,当容器关闭时,调用DisposableBean#afterPropertiesSet()方法17,对于15,调用destroy-method属性指定的方法二,bean生命周期方法的分类:1,Bean自身的方法:例如,Bean构造函数实例化Bean,调用Setter设置Bean属性值,init-method和destroy-method所指定的方法;2,Bean级生命周期接口方法:例如,BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean。这些接口的方法由Bean类直接实现3,容器级生命周期接口方法:例如,InstantiationAwareBeanPostProcessor和BeanPostProcessor,一般称为后处理器,后处理器接口一般不由Bean本身实现,独立于Bean,后处理器的影响是全局性的。三,如果要实现多个后处理器,需要多个后处理器同时实现org.springframework.core.Ordered接口,按照特定的顺序来执行这些后处理器。
5 在IoC容器中装配Bean
Spring配置概述
Spirng容器高层视图
Spring容器启动成功,需要具备三个条件:1,spring框架的包都已经在classpath中2,应用程序提供了完整的Bean配置信息3,Bean的类都已经放到应用程序的类路径下
Bean配置信息是Bean的元数据信息,由一下4个方面组成:1,bean的实现类2,bean的属性信息,如数据源源的连接数、用户名、密码3,bean的依赖关系,Spring根据依赖关系配置完成Bean之间的装配4,bean的行为配置,如生命周期范围及生命周期各过程的回调函数
基于xml的配置
5.2 Bean基本配置
5.2.1 装配一个Bean
<bean id=\"foo\" class=\"com.smart.foo\" />id为这个Bean的名称
5.2.2 Bean的命名
bean的id是唯一的bean的name属性可以是多个用“,”隔开<bean name=\
5.3 依赖注入
5.3.1 属性注入
<property name=\"maxSpeed\"><value>200</value></property>xxx的属性名对应setXxx()方法
javaBean要求“变量的前两个字母要么全部大写,要么全部小写”
5.3.2 构造函数注入
按类型匹配入参:<constructor-arg type=\"java.lang.String\">
按索引匹配入参:<constructor-arg index=\"0\">
联合使用类型和索引匹配入参:<constructor-arg index=\"0\" type=\"java.lang.String\">
通过自身类型反射匹配入参:<constructor-arg> <ref bean=\"car\"></constructor-arg>
循环依赖问题:car构造依赖bossboss构造依赖carspring启动时,无法启动,只要将构造函数注入调整为属性注入就可以
5.3.3 工厂方法注入
非静态工方法:<bean id=\"carFactory\" class=\"me.leifgao.bean.CarFactory\"/><bean id=\"car5\" factory-bean=\"carFactory\" factory-method=\"createHongQiCar\"/>
静态工方法:<bean id=\"car5\" class=\"me.leifgao.bean.CarFactory\" factory-method=\"createHongQiCar\"/>
5.3.4 选择注入方式的考量
5.4 注入参数详解
5.4.1 字面值
“字面值”:一般是指可用字符串表示的值,这些值可以通过<value>元素标签进行注入
spring提供了编辑器,可以将以字符串表示的字面值转化为内部变量的相对应类型
xml特殊实体符号:<:< >:> &:& \":" ':'当遇到这些特殊符号时有两种处理方式:1,![CDATA[红旗&ca]] (也就是![CDATA[...]])2,红旗&ca [<] : [<] [>] : [>] [&] : [&] [\"] : ["] ['] : [']
spring不会忽略value标签中的空格符号
5.4.2 引用其他Bean
<ref>元素可以通过三个属性引用容器中的其他Bean:1,bean:引用同一容器或父容器的Bean2,local:只能引用同一配置文件中定义的Bean3,parent:引用父容器中的Bean
5.4.3 内部Bean
如果一个bean只被另一个Bean引用而不会被容器中的任何其它Bean引用,则可以以内部Bean的方式注入到另一个Bean中: <bean id = \"boss\" class=\"com.baobaotao.attr.Boss\"> <property name = \"car\"> <bean class = \"com.baobaotao.attr.Car\"> <property name=\"maxSpeed\" value=\"200\"/> <property name=\"price\" value=\"20000.00\"/> </bean> </property> </bean>则内部Car Bean不能被其他Bean引用,即使提供了id、name、scope属性
5.4.4 null值
<bean id=\"car\" class=\"com.baobaotao.attr.Car\"> <property name=\"brand\"><value></value></property></bean>spring会解析成空字符串 <property name=\"brand\"><null/></property>spring会解析成null
5.4.5 级联属性配置
级联属性配置:<bean id=\"boss\" class=\"com.baobaotao.arrt.Boos\"> <property name=\"car.brand\" value=\"吉利CT50\"/></bean>在spring3.0以前,上述配置,需要在boos类中显示实例化 private Car car = new Car();在spring3.0以后,则无需配置,spring会自动为内置属性实例化一个对象
5.4.6 集合类型属性
Set:<bean id=\"boss\" class=\"com.baobaotao.attr.Boss\"> <property name=\"favorites\"> <set> <value>看报</value> <value>赛车</value> <value>高尔夫</value> </set> </property></bean>
Map:public class Boss{ private Map jobs = new HashMap(); set();get();}<bean id=\"boss\" class=\"com.baobaotao.attr.Boss\"> <property name=\"jobs\"> <map> <entry> <key><value>AM</value></key> <value>会见客户</value> </entry> <entry> <key><value>PM</value></key> <value>公司内部会议</value> </entry> </map> </property></bean>
Properties:<bean id=\"boss\" class=\"com.baobaotao.attr.Boss\"> <property name=\"favorites\"> <props> <prop key=\"jobMail\">leif@vipshop.com</prop> <prop key=\"lifeMail\">leif@gmail.com</prop> </set> </property></bean>
集合合并:<bean id=\"parentBoss\" abstract=\"true\" class=\"com.baobaotao.attr.Boss\"> <property name=\"favorites\"> <set> <value>爬山</value> <value>旅游</value> </set> </property><bean><bean id=\"childBoss\" parent=\"parentBoss\" class=\"com.baobaotao.attr.Boss\"> <property name=\"favorites\"> <set merge=\"true\"> <value>爬山</value> <value>旅游</value> </set> </property><bean>最终childBoss将拥有5个元素
通过util命名空间配置集合类型的Bean:List类型的Bean:<util:list id=\"favoriteList\" list-class=\"java.util.LinkedList\"> <value>看报</value> <value>赛车</value> <value>高尔夫</value></util:list>Set类型的Bean:<util:set id=\"favoriteList\"> <value>看报</value> <value>赛车</value> <value>高尔夫</value></util:set>Map类型的Bean:<util:map id=\"emails\"> <entry key=\"AM\" value=\"会见客户\"/> <entry key=\"PM\" value=\"公司内部会议\
5.4.7 简化配置方式
使用P命名空间:p:<属性名>=\"xxx\"p:<属性名>-ref=\"xxx\"
5.4.8 自动装配
autowire=\"<自动装配的类型>\"byName: 根据名称自动匹配。spring将容器中名字为car的Bean装配到Boss中的名为car的属性。byType: 根据类型自动匹配。spring将容器中Car类型的Bean装配到Boss中的Car类型的属性中。constructor: 与ByType类似,如果Boss有一个构造函数,该函数有一个Car类型的入参,spring自动将容器中Car类型的Bean作为入参,如果没有找到,则报错。autodetect: 如果Bean提供了默认的构造函数,则采用byType;否则采用constructor。
<beans>元素中的 default-autowire 属性可以配置全局的自动匹配,默认值为no。
基于注解的配置默认采用byType自动装配策略
5.5 方法注入
5.5.1 lookup方法注入
5.5.2 方法替换
pulic class Boss1{ public Car getCar(){ Car car = new Car(); car.setBrand(\"宝马Z4\
5.6 <bean>之间的关系
5.6.1 继承
<bean id=\"abstractCar\" class=\"com.baobaotao.tagdepend.Car\" p:brand=\"奥迪\" p:price=\"2000.00\" p:color=\"黑色\" abstract=\"true\"/><bean id =\"car3\" p:color=\"红色\" parent=\"abstractCar/\"><bean id =\"car4\" p:color=\"白色\" parent=\"abstractCar/\">父Bean申明了 abstract=\"true\" 表示这个bean不能被实例化
5.6.2 依赖
<bean id=\"manager\" class=\"com.baobaotao.tagdepend.CacheManager\" depends-on=\"sysInit\" /><bean id=\"sysInit\" class=\"com.baobaotao.tagdepend.SysInit\" />这样可以保证manager类被实例化前, sysInit会先被实例化
5.6.3 引用
<bean id=\"car\" class=\"com.baobaotao.tagdepend.Car\" /><bean id=\"boss\" class=\"com.baobaotao.tagdepend.Boss\"> <property name=\"carId\"> <idref bean=\"car\" /> </property></bean>通过这样的配置,spring在启动时会检查引用的正确性
5.7 整合多个配置文件
<import resource=\"classpath:com/babatao/impl/beans1.xml\">
5.8 Bean作用域
5.8.1 singleton作用域
任何通过容器的getBean(\"car\")方法返回的实例都指向同一个Bean
如不不希望容器启动时提前实例化singleton的bean,可以通过lazy-init进行控制<bean id=\"boss1\" class=\"com.babaotao.scope.Boss\" p:car-ref=\"car\" lazy-init=\"true\" />如果该Bean被其他需要提前实例化的Bean引用到,Spring将忽略延迟实例化的设置
5.8.2 prototype作用域
默认情况下,spring容器在启动时不实例化prototype的bean。spring容器将prototype的Bean交给调用者后,就不在管理它的生命周期了。
5.8.3 web应用环境相关的作用域
需要在web容器中进行额外的配置servlet2.3之前:<web-app> <filter> <filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter-mapping> <filter-name>requestContextFileter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>高版本的web容器中:<web-app> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener></web-app>
request作用域:<bean name=\"car\" class=\"com.baobaotao.scope.Car\" scope=\"request\
session作用域:<bean name=\"car\" class=\"com.baobaotao.scope.Car\" scope=\"session\
5.8.4 作用域依赖问题
如果将Web相关的作用域的Bean注入到singleton或prototype的Bean中,需要一些额外的配置,才可以生效
<bean name=\"car\" class=\"com.baobaotao.scope.Car\" scope=\"request\"> <aop:scoped-proxy/></bean><bean id=\"boss\" class=\"com.baobaotao.scope.Boss\"> <property name=\"car\" ref=\"car\" /></bean>当boss bean在web环境下,调用car bean时,spring aop 将启用动态代理判断boss bean位于哪个HTTP请求线程中,并从对应的HTTP请求线程中获取对应的car bean
5.9 FactoryBean
FactoryBean 包含三个接口T getObject(): 返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中的单实例缓存池中;boolean isSingleton():确定由FactoryBean创建的Bean的作用域是singleton还是prototypeClass<?> getObjectType():返回FactoryBean创建Bean的类型
当getBean(\"car\")时,相当于调用CarFactoryBean#getObject()返回对象。如果用户希望获取CarFactoryBean自身的实例,则getBean(\"&car\")
5.10 基于注解的配置
5.10.1 使用注解定义Bean
@Component(\"userDao\")public class UserDao {}相当于在xml配置文件中<bean id=\"userDao\" class=\"com.baobatao.anno.UserDao\"/>
@Repository: 用于对DAO实现类进行标注@Service: 用于对Service实现类进行标注@Controller: 用于对Controller实现类进行标注在@Conmponent之外提供这三个特殊注解,是为了赋予一些特殊的功能
5.10.2 使用注解配置信息启动Spring容器
spring的context的命名空间,提供了扫描类包的功能
<context:component-scan base-package=\"com.baobaotao\" resource-pattern=\"anno/*.class\">则此时,Spring会扫描com.baobaotao包下面,anno包中的所有类
<context:component-scan base-package=\"com.baobaotao\"> <context:include-filter type=\"regex\" expressionn=\"com\\.baobaotao\\.anno.*\" /> <context:exclude-filter type=\"aspectj\" expression=\"com.baobaotao..*Controller+\" /></context:component-scan><context:include-filter>表示要包含的目标类<context:exclude-filter>表示要排除在外的项目一个<context:component-scan>下可以拥有若干个<context:exclude-filter>和<context:include-filter>
类别 示例 说明annotation com.baobaotao.XxxAnnotation 所有标注了XxxAnnotation的类。assignable com.baobaotao.XxxService 所有继承或扩展XxxService的类。aspectj com.baobaotao..*Service+ 所有类名以Service结束的类及继承或扩 展他们的类regex com\\.baobaotao\\.anno\\..* 所有com.baobaotao.anno类包下的 类。该类型采用正则表达式过滤custom com.baobaotao.XxxTypeFilter 采用XxxTypeFile 通过代码的方式根据 过滤规则。该类必须实现org.springframework.core.type.TypeFilter接口
5.10.3 自动装配Bean
使用@Autowired进行自动注入@Autowired默认按类型匹配的方式自动注入,在容器中查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入到@Autowired标注的变量中
使用@Autowired的required属性如果容器中没有一个和标注变量类型匹配的Bean,Spring容器启动将报NoSuchBeanDefinitionException的异常。如果希望即使没匹配也不报错,则可以使用@Autowired(required=false)进行标注
@Qualifier指定注入Bean的名称如果容器中有多个Bean匹配时,可以通过@Qualifier注解限定Bean的名称。@Qualifier(\"userDao\")private UserDao userDao;
对类方法进行标注自动将LogDao传给方法入参:@Autowiredpublic void setLogDao(LogDao logDao){ this.logDao = logDao}自动将名为userDao的Bean传给方法入参@Autowired@Qualifier(\"userDao\")public void setUserDao(UserDao userDao){ this.userDao = userDao}
如果方法有多个入参,默认情况下,Spring自动选择匹配入参类型的Bean进行注入。也允许对入参标注@Qualifier以指定Bean的名称。@Autowiredpublic void init(Qualifier(\"userDao\
在bean上标注 @Lazy ,然后再注入的地方标注 @Lazy和@Repository,则延迟到调用此属性的时候才会注入值
@Resourceprivate void setCar(Car car){ .....}如果@Resource未指定\"car\"属性,则会根据属性方法得到需要注入bean的名称。@Resource是按照名称进行注入的@Inject和@Autowired一样,也是按照类型匹配注入Bean的,但是没有required属性。
5.10.4 Bean作用范围及生命过程方法
@Scope(\"prototype\")指定Bean的作用范围
5.11 基于java类的配置
5.11.1 使用java类提供Bean定义信息
@Configurationpublic class AppConf{ @Bean public UserDao userDao { return new UserDao(); }}@Configuration注解,说明这个类可用于提供Bean的定义信息@Bean的类方法相当于提供了一个Bean的定义信息Bean的类型由方法名返回值类型决定,名称默认和方法名相同。也可以通过入参显示指定Bean名称,如@Bean(name=\"userDao\")
@Configuration注解本身已经标注了@Component注解,所以标注了@Configuration的类,可以像普通的Bean一样被注入到其他Bean中。调用标注了@Bean注解的方法时,并不是只是简单的调用方法,spring会对这些方法进行改造(AOP增强),所以调用这些@Bean标注的方法时,是从容器中返回相应的Bean。在@Bean处,还可以标注@Scope(\"prototype\")注解
5.11.2 使用基于Java类的配置信息启动Spring容器
直接通过@Configuration类启动Spring容器ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class)直接使用AppConf类的配置信息启动Spring容器。还支持加载多个@Configuration配置类,但是必须要刷新。AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.register(DaoConfig.class);ctx.register(ServiceConfig.class);ctx.refresh();也可以通过@Import将多个配置类组装到一起@Configuration@Import(DaoConfig.class)public class ServiceConfig{}
通过XML配置文件引用@Configuration的配置因为@Configuration的注解本身相当于一个标注了@Component的类,所以可以被<context:component-sacn>扫包扫到就行<context : component-scan base-package=\"...\" resource-pattern=\"AppConf.class\">
通过Configuration配置类引用XML配置信息假设app.xml配置文件中定义了两个类,@Configuration的类想用这两个类在@Configuration配置类中标注@ImportResource@Configuration@ImportResource(\"classpath:com/baobaotao/conf/beans3.xml\")public class LogonAppConfig{}
5.12 基于Groovy DSL的配置
5.13 通过编码方式动态添加Bean
5.13.1 通过DefaultListableBeanFactory
5.13.2 扩展自定义标签
1,采用XSD描述自定义标签的元素属性 就是编写自定义xml的shema内容
2,编写服务标签解析类 需要实现 BeanDefinitionParser#parse()
3,注册Spring命名空间解析器 需要实现NamespaceHandlerSupport#init()
4,告诉Spring自定义标签的文档结构及解析它的类 在源码resources目录创建META-INF文件夹,创建spring.handlers和spring.schemas两个文件 spring.schemas : http\\://www.smart.com.schema/service.xds=com/smart/schema/userservice.xsd spring.handlers: http\\://www.smart.com/schema/service=com.smart.dynamic.UserServiceNamespaceHandler
6 Spring容器高级主题
6.1 Spring容器的技术内幕
6.1.1 内部工作机制
6.1.2 BeanDefinition
6.1.3 InstantiationStrategy
通过InstantiationStrategy负责根据BeanDefinition对象创建一个Bean实例。
SimpleInstantiationStrategy是最常用的实例化策略,该策略利用Bean实现类的默认构造函数。带参构造函数或工厂方法创建Bean的实例
CglibSubclassingInstantiationStrategy扩展了SimpleInstantiationStrategy,利用CGLib类库为Bean动态生成子类,在子类中生成方法注入的逻辑,然后利用这个子类创建Bean的实例
InstantiationStrategy仅负责实例化Bean的操作,不会参与Bean属性的设置工作。属性填充由BeanWrapper完成。
6.1.4 BeanWrapper
6.2 属性编辑器
6.2.1 JavaBean编辑器
PropertyEditor接口Object getValue(): 返回属性当前值,基本类型被封装成对应的封装类实体void setValue(Object newValue): 设置属性的值,基本类型一封装类传入String getAsText(): 将属性对象用一个字符串表示,默认返回null,表示不能以字符串表示void setAsTest(): 用一个字符串去更新属性的内部值,这个字符串一般从外部属性编辑器传入String[] getTags(): 返回几个有效的候选项(如boolean 有 true,false),然后属性编辑器以下拉框的方式显示出来。String getJavaInitializationString(): 为属性提供一个表示初始值的字符串
6.2.2 Spring默认属性编辑器
Spring在PropertyEditorRegistrySupport中为常见的属性类提供了默认的属性编辑器。
6.2.3 自定义属性编辑器
在Boss类中配置Car类,有两种方法:一,在配置文件中给car配置一个<bean>,然后再Boss的配置中通过ref引用car Bean。 二,给Car提供一个自定义的属性编辑器,然后通过字面值给Boss的car属性配置值。
6.3 使用外部属性文件
6.3.1 PropertyPlaceholderConfigurer属性文件
<bean class=\"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer\" p : location=\"classpath:com/smart/placeholder/jdbc.properties\" p : fileEncoding=\"utf-8\" /><bean id=\"dataSource\" class=\"org.apache.commons.dbcp.BasicDataSource\" destroy-method=\"close\" p : driverClassName=\"${driverClassName}\" p : url=\"${url}\" p : username=\"$usernName\" p : password=\"${password}\" />
PropertyPlaceholderConfigurer的其他属性:locations : 一个属性文件,locations指定。多个属性文件,通过locations属性进行设置。像配置List一样配置locations属性。fileEncoding : Spring默认使用操作系统的编码,其他编码需要指定order : 如果配置了多个PropertyPlaceholderConfigurer,则通过该属性指定有限顺序placeholderPrefix : \"${\"为默认的占位前缀符,可以更改placeholderSuffix : \"}\"为默认的占位后缀,可以更改
也可以使用context命名空间定义属性文件,相比于PropertyPlaceholderConfigurer配置,这种方法更优雅<context : property-placeholder location=\"classpath:com/smart/placeholder/jdbc.properties\" />
在XML文件中,使用${propName}引用属性值在类中,使用@Value注解自动注入容器已有的属性
6.3.2 使用加密的属性文件
6.3.3 属性文件自身的引用
可以在jdbc.properties中引用其他定义的属性值dbName=sampledburl=jddbc:mysql://localhost:3306/${dbName}
6.4 引用Bean的属性值
在Spring3.0中,可以通过#{beanName.beanProp}的方式引用另一个Bean的值
XML文件中, 直接使用#{beanName.beanProp}类中,@Value(\"#{beanName.propName}\")使用
6.5 国际化信息
6.6 容器事件
事件源 : 事件产生者事件监听器注册表 : 保存事件监听器事件广播器 : 负责把事件通知给事件监听器
6.6.1 Spring事件类结构
事件类ApplicationEvent#ApplicationEvent(Object source) : 通过source指定事件源ApplicationContextEvent:容器事件,有四个子类ContextClosedEvent : 容器关闭事件ContextRefreshedEvent :容器刷新事件 ContextStartedEvent :容器开始事件ContextStoppedEvent:容器停止事件
事件监听器接口ApplicationListener#onApplicationEvent(E event):该方法接收ApplicationEvent事件对象,编写处理事件的代码SmartApplicationListener接口Spring3.0新增的:boolean supprotsEventType(Class<? extends ApplicationEvent> eventType) :指定监听器支持哪种类型的容器事件boolean supportsSourceType(Class<?> sourceType) :指定监听器仅对何种事件源对象作出响应GenericApplicationListener接口是Spring4.2新增的。boolean supprotsEventType(ResolvableType eventType) : 指定支持的事件类型。boolean supportsSourceType(Class<?> sourceType) : 指定监听器对何种事件源作出响应。
事件广播器ApplicationEventMulticasterAbstractApplicationEventMulticasterSimpleApplicationEventMulticaster
6.6.2 解构Spring事件体系的具体实现
6.6.3 一个实例
7 Spring AOP基础
7.1 AOP概览
7.1.1 AOP到底是什么
7.1.2 AOP术语
1.连接点(Joinpoint)连接点由两个信息确定:一是用方法表示的程序执行点;二是用相对位置表示的方位
2.切点(Pointcut)通过类和方法作为条件,查询到连接点中的执行点(因为切点不包含方位信息)
3.增强(Advice)由两个组成,一是一段代码,二是方位信息
4.目标对象(Target)待增强织入的目标类
5.引介(Introduction)一种特殊的增强,给类添加一些属性和方法。
6.织入(Weaving)将增强添加到目标类的具体连接点的过程AOP有三种织入方式(1) 编译期织入,需要特殊的Java编译器(2) 类装载织入,需要特殊的类装载器(3) 动态代理,在运行期为目标类添加增强生成子类的方式。Spring采用动态代理,AspectJ采(1)和(2)
7.代理(Proxy)一个类被AOP增强后,就产生了一个结果类,融合了原类和增强逻辑的代理类。代理类既可以是和原类具有相同接口的类,也可能是原类的子类,所以才可以用和原类相同的方式调用
8.切面(Aspect)切面由切点和增强(引介)组成。
7.2 基础知识
7.2.1 带有横切逻辑的实例
7.2.2 JDK动态代理
JDK动态代理,涉及到 Proxy和InvocationHandler
见springDemo项目代码
7.2.3 CGLib动态代理
使用JDK创建代理只能为接口创建实例。
见springDemo
7.2.4 AOP联盟
http://aopalliance.sourceforge.net
7.2.5 代理知识小结
7.3 创建增强类
Spring使用增强类定义横切逻辑
7.3.1 增强类型
前置增强:org.springframmework.aop.BeforeAdvice代表前置增强由于spring只支持方法级的增强,所以MethodBeforeAdvice是目前可用的前置增强
后置增强:org.springframmework.aop.AfterReturningAdvice代表后置增强,表示方法执行后实施增强
环绕增强:org.aopalliance.intercept.MethodInterceptor代表环绕增强,表示在目标方法执行前后实施增强
异常抛出增强:org.springframework.aop.ThrowsAdvice代表抛出异常增强,表示在目标方法抛出异常后实施增强。
引介增强:org.springframework.aop.IntroductionInterceptor代表引介增强,表示在目标类中添加一些新的方法和属性
7.3.2 前置增强
springDemo代码
Spring定义了org.springframework.aop.framework.AopProxy接口Cglib2AopProxy使用Cglib动态代理技术JdkDynamicAopProxy使用JDK动态代理技术
ProxyFactory可以添加多个增强,调用顺序和添加顺序一致。
xml配置<bean id=\"waiter\" class=\"org.springframework.aop.framework.ProxyFactoryBean\" p:proxyInterfaces=\"com.smart.advice.Waiter\" p:interceptorNames=\"greetingAdvice\" p:target-ref=\"target\" />target : 代理类的目标对象proxyInterfaces : 代理所要实现的接口,可以是多个接口interceptorNames : 切面方法抽取出来的bean,这些bean必须实现org.aopalliance.MethodInterceptor 或org.springframework.aop.Advisor的bean,配置中的顺序对应调用的顺序。singleton : 返回的单例是否是单实例,默认单实例optimize : 当设置为true时,强制使用Cglib动态代理proxyTargetClass : 是否对类进行代理。当设置为true时,使用Cglib动态代理
7.3.3 后置增强
实现AfterReturningAdvice#afterReturning来定义后置增强的逻辑
最好使用<property name=\"interceptorNames\"> <list> <idref local=\"greetingBefore\"> <idref local=\"greetingAfter\"> </list> </property>
7.3.4 环绕增强
实现MethodInterceptor#invoke()方法会在target类的方法执行前后调用
7.3.5 异常抛出增强
实现ThrowsAdvice#afterThrowing()方法
7.3.6 引介增强
7.4 创建切面
Spring支持两种方法匹配器 : 静态方法匹配器和动态方法匹配器静态方法匹配器 : 仅对方法名签名(包括方法名和入参类型及顺序)进行匹配,静态匹配仅会匹配一次。动态方法匹配器 : 在运行期检查入参的值,动态方法每次调用方法都会匹配。
7.4.2 切面类型
增强既包含横切代码,又包含部分连接点信息,所以可以通过增强生成一个切面但切点必须结合增强才能生成切面,应为切点不包含横切代码
切面可以分为3类:一般切面、切点切面、引介切面Advisor:代表一般切面,仅包含一个Advice,代表的横切的连接点是所有目标类的所有方法PointcutAdvisor:包含Advice和Pointcut两个类。IntroductionAdvisor : 应用于类层面上
PointcutAdvisor主要有6个具体的实现类DefaultPointcutAdvisor:通过任意Pointcut和Advice定义一个切面,不支持引介的切面类型NameMatchMethodPointcutAdvisor:按照方法名定义切点的切面RegexpMethodPointcutAdvisor:按照正则表达式匹配方法名进行切点定义的切面StaticMethodMatcherPointcutAdvisor:静态方法匹配器切点定义的切面AspectJExpressionPointcutAdvisor:用于AspectJ切点表达式定义切点的切面AspectJPointcutAdvisor:用于AspectJ语法定义切点的切面
7.4.3 静态普通方法名匹配切面
7.4.4 静态正则表达式方法匹配切面
RegexpMethodPointcutAdvisor是正则表达式方法匹配的切面实现类
pattern : 只能定义一个匹配模式串patterns : 定义多个模式匹配串 advice : 定义增强order : 切面在织入时对应的顺序
7.4.5 动态切面
使用DefaultPointcutAdvisor和DynamicMethodMatcherPointcut来完成动态切面
springDemo
7.4.6 流程切面
使用DefaultPointcutAdvisor和ControlFlowPointcut来完成动态切面
7.4.7 复合切点切面
ComposablePointcut提供了3个交集运算的方法:ComposablePointcut intersection(ClassFilter filter) : 将复合切点和一个ClassFilter对象进行交集运算,得到结果复合切点ComposablePointcut intersection(MethodMatcher mm) : 将复合切点和一个MethodMatcher对象进行交集运算,得到结果复合切点ComposablePointcut intersection(Pointcut other) :将复合切点和一个切点对象进行交集运算,得到一个结果复合切点
ComposablePointcut提供了两个并集运算方法:ComposablePointcut union(ClassFilter filter) : 将复合切点和一个ClassFilter对象进行交并集运算,得到一个结果复合切点ComposablePointcut union(MethodMatcher mm) : 将复合切点和一个MethodMatcher对象进行交并集运算,得到一个结果复合切点
7.4.8 引介切面
7.5 自动创建代理
8 基于@AspectJ和Schema的AOP
8.3 使用@AspectJ
8.3.3 通过配置使用@AspectJ切面
第一种: 配置切面bean,配置自动代理创建器<bean class=\"me.leifgao.PreGreetingAspect\"><bean class=\"org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator\">
第二种: 配置切面bean,配置自动代理创建器<bean class=\"me.leifgao.PreGreetingAspect\
8.4 @AspectJ语法基础
8.4.1 切点表达式函数
9个@AspectJ切点表达式函数,大致分为4类:方法切点函数:通过目标类方法的信息定义连接点方法入参切点函数:通过目标类方法入参定义连接点目标类切点函数:通过目标类的类型定义连接点代理类切点函数:通过目标类的代理类定义连接点
类别 函数 入参 说明------------------------------------------------------------------------------------方法切点函数 execution() 方法名正则串 目标类中所有符合正则串的方法 @annotation() 注解的类名 目标类中所有标注了该注解的方法方法入参切点函数 args() 类名 目标类方法的入参符合该类型的所有方法 @args() 注解的类名 目标类的方法的入参标注了该注解的所有方法目标类切点函数 within() 类名正则串 符合类名正则串的所有类的所有方法 target() 类名 目标类匹配类名,则目标类及其子类所有方法 @within() 注解的类名 目标类标注了该注解,则目标类及其子类所有方法 @target() 注解的类名 目标类标注了该注解,则目标类所有方法代理类切点函数 this() 类名
8.4.2 在表达式函数中使用通配符
* :匹配任意字符,但是只是一个元素.. : 匹配任意字符,可以匹配多个元素。表示类时,必须和*联合使用,表示入参时,可单独使用+: 匹配指定类和该类的子类
@Aspect按支持程度分三类:支持所有通配符:execution() 和 within()仅支持\"+\
8.4.3 逻辑运算符
&& : 与操作,xml中是 &&
|| : 或操作
!: 非操作
8.4.4 不同的增强类型
@Before : 前置增强
@AfterReturning : 后置增强,pointcut会覆盖 value值
@Around : 环绕增强
@AfterThrowing : 抛出增强,pointcut会覆盖value值
@After : 不关抛出异常还是正常返回,该增强都会执行。
@DeclareParents : 引介增强
8.5 切点函数详解
8.5.1 @annotation()
@annotation()表示标注了某个注解的所有方法
8.5.2 execution()
execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)除了 返回类型模式,方法名模式,参数模式不可省略,其他都可省略
1,通过方法签名定义切点2,通过类定义切点3,通过类包定义切点4,通过方法入参定义切点
8.5.3 args()和@args()
args() 目标类方法入参是指定类(包含子类)时,切点匹配
@args() 目标类方法入参标注了指定的注解时,切点匹配入参类型点:方法签名中入参类型在继承树中的位置注解点:标注了注解的类在继承树中的位置入参类型点 低于 注解点 不能匹配入参类型点 高于 注解点 注解点所在类及子孙类都匹配
8.5.4 within()
within(<类匹配模式>):连接点的最小范围只能是类不匹配子类??
8.5.5 @within()和@target()
@target(M) : 标注了@M的目标类@within(M) : 标注了@M的目标类及子孙类
8.5.6 target() 和 this()
target(M):如果目标类按类型匹配M,则目标类所有方法都匹配包含子孙类
this(M) :
8.6 @AspectJ进阶
8.6.1 切点复合运算
&& , ||, !
8.6.2 切点命名
匿名切点:直接在增强处定义的切点
@Pointcut(\"within(xxx)\")private void inPackage(){}
8.6.3 增强织入顺序
同一个切面类中,按照定义的顺序织入
不同切面中,如果继承了org.springframework.core.Ordered接口,则由接口方法的顺序号决定(小的先织入)
不同切面中,如果没有继承org.springframework.core.Ordered接口,则不确定
8.6.4 访问连接点信息
1,JoinPointObject[] getArgs() : 获取连接点方法运行时的入参列表Signature getSignature(): 获取连接点的方法签名对象Object getTarget() : 获取连接点所在的目标对象Object getThis() : 获取代理对象自身
1,ProceedingJoinPoint 比 JoinPoint多了两个方法:Object proceed() throws Throwable : 执行目标对象的连接点处的方法Object proceed(Object[] args) throws Throwable : 使用新参数执行目标对象的方法
8.6.5 绑定连接点方法入参
args() 绑定连接点方法的入参@annotation()绑定连接点方法的注解@args()绑定连接点方法的入参的注解
8.6.6 绑定代理对象
this()或target()函数可绑定被代理对象的实例,也就是目标类
8.6.7 绑定类注解对象
@within()和@target()函数可以将目标类注解对象绑定到增强方法上
8.6.8 绑定返回值
@AfterReturning( returning=\"retVal\")
8.6.9 绑定抛出的异常
@AfterThrowing(throwing = \"xxx\")
8.7 基于Schema配置切面
8.7.1 一个简单切面的配置
见P301
8.7.2 配置命名切点
8.7.3 各种增强类型的配置
后置增强<aop:after-returning method=\"xxx\" pointcut=\"xxx\" returing=\"xxx\"/>
环绕增强<aop:around method=\"xxx\" pointcut=\"xxx\"/>
抛出异常增强<aop:after-throwing method=\"xxx\" pointcut=\"xxx\" throwing=\"xxx\"/>
Final增强<aop:after method=\"xxx\" pointcut=\"xxx\"/>
引介增强<aop:declare-parents implement-interface=\"xxx\" default-impl=\"xxx\" types-matching=\"\"/>
8.7.4 绑定连接点信息
8.7.5 Advisor配置
advisor 切点和增强的复合体,包含一个切点,一个增强
8.8 混合切面类型
四种定义切面的方式:1,基于@AspectJ注解的方式2,基于<aop:aspect>的方式3,基于<aop:advisor>的方式4,基于Advisor类的方式
11 Spring的事务管理
11.1 数据库事务基础知识
11.1.1何为数据库事务
多条SQL,要么都执行成功,要么执行失败
数据库事务满足四个特性:1,原子性 : 2,一致性:事务操作后,数据库所处的状态和他的业务规则是一致的3,隔离性:在并发数据操作时,不同的事务拥有各自的事务空间,互相不影响。隔离级别越高,数据一致性越好,但并发性越弱。4,持久性:事务提交成功后,事务中的所有数据都必须持久化到数据库中。
11.1.2数据并发问题
1.脏读(dirty read)A事务读取B事务尚未提交的更改数据。
2.不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改数据
3.幻想读(phantom read):A事务读取了B事务新增的数据
4.第一类丢失更新A事务撤销时,把已经提交的B事务的更新数据覆盖了
5.第二类丢失更新A事务提交时,把已经提交的B事务的更新数据覆盖了
11.1.3数据库锁机制
表锁行锁
共享锁独占锁
行共享锁:行独占锁:表共享锁:表共享行独占锁定:表独占锁定:
11.1.4事务隔离级别
11.1.5 JDBC对事务的支持
11.2 TheradLocal基础知识
11.2.2 ThreadLocal的接口方法
void set(T value):设置当前线程的线程局部变量的值
public T get():返回当前线程所对应的线程局部变量
public void remove():将当前线程局部变量的值删除
protected T initialValue():返回该线程局部变量的初始值
11.3 Spring对事务管理的支持
11.3.3 事务同步管理器
Spring的将JDBC的Connection,Hibernate的Session等访问数据库的连接或会话对象统称为资源,这些资源在同一时刻是不能多线程共享的。
11.3.4 事务传播行为
propagation_required : 当前没有事务,则新建一个事务。如果已经存在一个事务,则加入到这个事务中。
propagation_supports : 支持当前事务,如果当前没有事务,则以非事务方式执行。
propagation_mandatory :使用当前事务,如果当前没有事务,则抛出异常
propagation_requires_new :新建事务。如果当前存在事务,则把当前事务挂起
propagation_not_supported :以非事务方式执行操作,如果当前存在事务,则把当前事务挂起
propagation_never :以非事务方式执行。如果当前存在事务,则抛出异常
propagation_nested:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则执行required类似的操作
11.4 编程式的事务管理
TransactionTemplate主要有两个方法:void setTransactionManager(PlatformTransactionManager transactionManager):设置事务管理器Object execute(TransactionCallback action) : 在TransactionCallback回调接口中定义需要以事务方式组织的数据访问逻辑
TransactionCallback只有一个方法 Object doInTransaction(TransactionStatus status)
11.5 使用XML配置申明式事务
11.5.2 使用原始的TransactionProxyFactoryBean
1.声明式事务配置声明事务管理器<bean id = \"txManager\" class=\"org.springframework.jdbc.datasource.DataSourceTransactionManager\"><property name=\"dataSource\" ref= \"dataSource\"></bean>需要实施事务增强的目标业务bean<bean id=\"xxxTarget\" class=\"package com.smart.service.xxx\" p:forumDao-ref=\"xxx\"/><bean id=\"bbtForum\" class=\"org.springframework.transaction.interceptor.TransactionProxyFactoryBean\" p:transactionManager-ref=\"txManager\" p:traget-ref=\"xxxTraget\"> <property name=\"transactionAttributes\"> <props> <prop key=\"get*\
11.5.3 基于aop/tx命名空间的配置
1.声明式事务配置声明事务管理器<bean id = \"txManager\" class=\"org.springframework.jdbc.datasource.DataSourceTransactionManager\"><property name=\"dataSource\" ref= \"dataSource\"></bean>使用切点表达式定义目标bean<aop : config> <aop:pointcut id=\"serviceMethod\" expression=\"execution(xxx)\" /> <aop:advisor pointcut-ref=\"serviceMethod\" advice-ref=\"txAdvice\"></aop : config>事务增强<tx : advice id=\"txAdvice\" transaction-manager=\"txManager\"> <tx:attributes> <tx:method name=\"xxx\" read-only=\"false\"/> <tx:method name=\"add*\" rollback-for=\"Exception\"/> <tx:method name=\"update*\"/> </tx:attributes></tx : advice>
11.6 使用注解配置声明式事务
11.6.1 使用@Transactional注解
对标注了@Transactional注解的Bean进行加工处理,以织入事务管理切面<tx:annotation-driven transaction-manager=\"txManager\"/><tx:annotation-driven>还有另外两个属性proxy-target-class : 如果为true,则CGLib来创建子类order : 如果需要织入其他切面,则可以控制顺序
@Transactional属性propagation:事务传播行为isolation:事务隔离级别readOnly:事务读写性timeout:超时时间rollbackFor:一组异常,遇到时进行回滚,类型为Class<? extends Throwable>[]rollbackForClassName:一组异常,遇到时回滚,类型为String[]noRollbackFor:一组异常,允到时不回滚noRollbackForClassName:一组异常,允到时不回滚
Spring建议在具体业务类上使用@Transactional注解,而不是在接口上
类级注解,适用于类中所有public的方法方法级注解会覆盖类注解
12 Spring的事务管理难点剖析
12.4 多线程的疑惑
12.4.1 Spring通过单实例化Bean简化多线程问题
一个类能以单实例的方式运行的前提是“无状态”的,即不能拥有状态化的成员变量
spring通过ThreadLocal将有状态的变量(如Connection等)本地线程化。
12.4.2 启动独立线程调用事务方法
在相同线程中进行相互嵌套调用的事务方法工作在相同的事务中。如果相互嵌套调用的方法工作在不同的线程中,则不同线程下的事务方法工作在不同的独立的事务中
12.6 特殊方法不可Spring AOP事务
12.6.1 哪些方法不能实施SpringAOP事务
基于接口动态代理的AOP事务增强来说只能是public 或 public final修饰符的方法。
基于CGlib字节码动态代理使用 final、static、private修饰符的方法不能被子类覆盖,无法实施SpringAop事务增强
12.7 数据连接泄露
12.7.1 底层连接资源的访问问题
Spring DAO的模板(JdbcTemplate、HibernateTemplate等),一定不会存在数据连接泄露问题
获取Spring管理的数据连接,有以下两种方法:1,使用数据资源获取工具类2,对数据源进行代理
12.7.2 Spring JDBC数据连接泄露
jdbcTemplate.getDataSource().getConnection() 这种直接获取的数据连接,如果最终没有释放,会造成数据库连接泄露
12.7.3 事务环境下通过DataSourceUtils获取数据连接
通过DataSourceUtils类获得的连接,不会存在泄露的情况(前提,在事务中获取)
12.7.4 无事务环境下通过DataSourceUtils获取数据连接
在非事务环境下,通过DataSourceUtils类获得的连接,也有可能会存在泄露的情况
需要显示调用 DataSourceUtils.releaseConnection()方法释放获取的连接。
12.7.5 JdbcTemplate如何方式数据泄露
在执行后,会调用DataSourceUtils#releaseConnection()方法释放连接
12.7.6 使用TransactionAwareDataSourceProxy
通过TransactionAwareDataSourceProxy代理的bean去获取数据库连接,和DataSourceUtils.getConnection()方法获取连接效果一样的。
13 使用Spring JDBC访问数据库
13.1 使用Spring JDBC
13.1.2 在DAO中使用JdbcTemplate
JdbcTemplate的属性:queryTimeout : 设置JdbcTemplate所创建的Statement查询数据时的最大超时时间fetchSize : 设置底层的ResultSet每次从数据库返回的行数。maxRows : 设置底层的ResultSet从数据库返回的最大行数ignoreWarnings : 是否忽略SQL的警告信息
13.2 基本的数据操作
13.2.1 更改数据
13.2.2 返回数据库的表自增主键值
autoGeneratedKeys 设置为 Statement.RETURN_GENERATED_KEYS : 绑定数据库产生的主键值Statement.NO_GENERATED_KEYS时,不绑定主键
13.2.3 批量更改数据
public int[] batchUpdate(String[] sql) : 多条sql语句组成一个数组,该方法批量方式执行SQL语句
int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) : 使用该方法对于同一结构的带参数SQL语句多次进行数据更新操做
14 整合其他ORM框架
14.1 Spring整合ORM技术
1.方便基础设施的搭建
2.异常封装
3.统一的事务管理
4.允许混合使用多个ORM框架
14.3 在Spring中使用MyBatis
14.3.1 配置SqlMapClient
每个MyBatis的应用都是以一个SqlSessionFactory对象的实例为核心。
提供可控制MyBatis框架运行行为的属性信息<settings> <setting name=\"lazyLoadingEnabled\" value=\"false\"></settings>定义全限定类名的别名,在映射文件中可以通过别名代替具体的类名<typeAliases> <typeAlias alias=\"Forum\" type=\"org.xxx.xxx.Forum\"> <typeAlias alias=\"Topic\" type=\"org.xxx.xxx.Topic\"></typeAliases>将MyBatis的所有映射文件组装起来<mappers> <mapper resource=\"org/xxx/xxx/Forum.xml\"> <mapper resource=\"org/xxx/xxx/Topic.xml\"></mappers>
resultType指定返回值parameterType指定入参类型 : 在sql中通过#{xxx}绑定parameterType参数,支持级联属性,如#{topic.forumId}
14.3.2 在Spring中配置MyBatis
bean id=\"sqlSessionFactory\" class=\"org.mybatis.spring.SqlSessionFactoryBean\"p : dataSource-ref=\"xxx\"p : configLocation=\"classpath : myBatisConfig.xml\"p : mapperLocations=\"classpath : xxx/xxx/xx/*.xml\"/>
14.3.3 编写MyBatis的DAO
<bean class=\"org.mybatis.spring.SqlSessionTemplate\"> <constructor-arg ref=\"sqlSessionFactory\"/> </bean>
定义一个接口,与xml文件匹配sessionTemplate.getMapper(xxxDao.class) : 将返回xxxDao接口的实例方法
MapperScannerConfigurer 将映射接口转换为Spring容器中的Bean。
14.4 DAO层设计
14.4.1 DAO基类设计
15 Spring Cache
15.1 缓存概述
15.2 掌握Spring Cache抽象
15.2.1 缓存注解
只有public方法的结果可以缓存,其他的不行
@Cacheable:加上了该注解的方法将缓存结结果缓存key的生成规则:1,没有入参,则使用SimpleKey.EMPTY作为key2,只有一个入参,则使用该入参作为key3,多个入参,返回包含所有入参的SimpleKey带条件的缓存Cacheable(condition=\"xxx\")
@CachePut :首先执行方法,然后将返回值放入缓存
@CacheEvict :删除缓存中的值allEntries :删除所有缓存beforeInvocation :在调用方法前,清除缓存
@Caching :是一个组注解,包含@Cacheable、@CacheEvict、@CachePut注解的数组
@CacheConfig :类注解,提供该类中所有缓存方法的配置信息
15.2.2 缓存管理器
SimpleCacheManager :通过SimpleCacheManager配置多个缓存列表。
NoOpCacheManager :测试,不缓存任何数据。
ConcurrentmapCacheManager :不需要定义缓存列表,默认使用JDK的ConcurrentMap。
CompositeCacheManager :可以组合配置多个上面的Manager
15.2.4 基于XML的Cache声明
<bean id=\"userService\" class=\"xxx.xxx.xxx\"/>缓存定义<cache:advice id=\"cacheAdvice\" cache-manager=\"cacheManager\"/> <cache : caching cache=\"users\"> <cache : cacheable method=\"findUser\" key=\"#userId\"> <cache : cache-evict method=\"loadUsers\" all-entries=\"true\"/> </cache : caching></cache:advice><aop:config> <aop:advisor advice-ref=\"cacheAdvice\" pointcut=\"xxxx\"/></aop:config>
15.2.5 以编程的方式初始化缓存
15.2.6 自定义缓存注解
15.3 配置Cache存储
15.3.1 缓存注解
16 任务调度和异步执行器
16.2 Quartz快速进阶
16.2.1 Quartz基础结构
Job :execute(JobExecutionContext context):通过实现该接口执行任务
JobDetail :Quartz在每次执行Job时,都重新创建一个Job实例,JobDetail接受一个Job的实现类,而不是实例。
Trigger :触发器,时间规则
Scheduler :代表一个Quartz独立运行容器,Trigger和JobDetail可以注册到Scheduler中
Job有一个StatefulJob子接口,代表有状态任务。无状态任务在执行时拥有自己的JobDataMap复制,对JobDataMap的更改不影响下次执行。有状态任务共享同一个JobDataMap实例,每次执行对JobDataMap的更改会影响下次执行。
一个Scheduler可以拥有多个 Trigger和多个JobDetail,可以分到不同的组中。组名和名称组成了对象的全名。同一个对象的全名不能相同。
16.2.2 使用SimpleTrigger
16.2.3 使用CronTrigger
1. Cron表达式
16.2.4 使用Calendar
16.2.5 任务调度信息存储
1. 通过配置文件调整任务调度信息的保存策略
12.查询数据库中的信息
16.3 在Spring中使用Quartz
16.3.1 创建JobDetail
bean id=\"jobDetail_1\" JobDetailFactoryBean配置:<bean id=\"jobDetail_1\" class=\"org.springframework.scheduling.quartz.JobDetailFactoryBean\" p:jobClass=\"com.smart.quartz.MyJob\"p:applicationContextJobDataKey=\"applicationContext\"><property name=\"jobDataAsMap\"> <map> <entry key=\"size\" value=\"10\"/> </map></property></bean>
bean id=\"jobDetail_1\" MethodInvokingJobDetailFactoryBean配置<bean id=\"jobDetail_1\" class=\"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean\" p:targetObject=\"myService\" p:targetMethod=\"doJob\" p:concurrent=\"false\"/>
16.3.2 创建Trigger
SimpleTriggerFactoryBean配置bean id=\"simpleTrigger\" class=\"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean\" bean id=\"simpleTrigger\" class=\"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean\" bean id=\"simpleTrigger\" class=\"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean\" <bean id=\"simpleTrigger\" class=\"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean\" p:jobDetail-ref=\"jobDetail_1\" p:startDelay=\"1000\" p:repeatInterval=\"2000\" p:repeatCount=\"100\"> <property name=\"jobDataAsMap\"> <map> <entry key=\"count\" value=\"10\"/> </map> </property></bean>
CronTriggerFactoryBean配置<bean id=\"checkImagesTrigger\" class=\"org.springframework.scheduling.quartz.CronTriggerFactoryBean\" p:jobDetail-ref=\"jobDetail_1\" p:cronExpression=\"0/5 * * * * ?\"/>
16.3.3 创建Scheduler
0 条评论
回复 删除
下一页