Spring,--22
是一个轻量级的控制反转和面向切面的容器框架 ---从大小和开销两方面而言Spring都是轻量的 ---通过控制反转的技术达到松耦合的目的 ---提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发 ---包含并管理应用对象的配置和生命周期,这个意义上是一种容器 ---将简单的组件配置,组合成为复杂的应用,这个意义上是框架 在spring上开发应用简单 在spring上开发应用方便 在spring上开发应用便捷 容器 提供了对多种技术的支持 --JMS --MQ支 --UnitTest AOP(事务管理 日志) 提供了众多方便应用的辅助类(JDBC Template等) 对主流应用框架(Hibernate等)提供了良好的支持
spring framework runtime
框架的概念:
框架就是制定一套规范或者规则(思想),大家(程序员)在该规范或者规则(思想)下工作。或者说就是使用别人搭好的舞台,你来做表演框架的特点:
--半成品 --封装了特定的处理流程和控制逻辑 --成熟的,不断升级改进的软件为什么?
-软件系统日趋复杂 重用度高,开发效率和质量提高 软件设计人员要专注于对领域的了解,使需求分析更充分。 易于上手、快速解决问题====================================================================================
spring——IOC及bean容器
一 接口
接口:只能有声明不能有实现,支持多重继承(在java8中接口可以拥有方法体) 抽象类:即可以有包含实现的声明也可以有不包含实现的声明 类:声明必须包含实现 接口实现的变动不会影响其他各层的调用,对公共服务非常重要二 IOC——Inverse of Control 控制反转
控制反转:控制权的转移,应用程序本身不负责依赖对象的创建与维护,而是由外部容器负责创建和维护。例如:买房子,我们不建造房子(不new对象),而是找开发商买房子(去容器中申请)。 依赖注入(DI)Dependency Injection:是一种实现方式,由IOC容器在运行期间,动态的将某种依赖关系注入到对象之中 目的:创建对象并且组装对象之间的关系
三 Spring的bean配置
在IOC容器中将所有的控制对象称作bean,Spring对于bean的使用有两种方式:基于spring-ioc.xml的配置和注解。 注意xml中关于bean的配置程序段 <bean id="oneInterface(自定义)" class="配置的实现类"></bean>
使用示例:
public void test(){
OneInterface interface=super.getBean("oneInterface");//获取bean,不需要new对象
interface.hello();//调用函数
}
一、Bean容器初始化基础:两个包
1. org.springframework.beans 的BeanFactory提供配置结构和基本功能,加载并初始化Bean 2. org.springframework.context 的 ApplicationContext保存了Bean对象并在Spring中被广泛使用二、ApplicationContext初始化方式:
1.本地文件 //磁盘目录文件: C://xxxx/xxx 2.Classpath //相对路径,相对与web工程来说 3.Web应用中依赖servlet或Listerner
================================================================================
Spring注入是指在启动Spring容器加载bean配置的时候,完成对变量的赋值行为
常用的两种注入方式:注入:是指IOC容器初始化A时,就把A的成员变量B 进行赋值。
1.设值注入 2.构造注入设值注入:给Private 属性设值
需要添加属性的setter方法,IOC容器会自动调用set方法给成员变量赋值 在配置文件的<bean>中添加<property name="xxx" ref="……"><bean>
<property name="xxx" ref="……"></bean>
构造注入:
需要提供相应的构造方法IOC容器调用bean的构造方法时会给成员变量赋值在配置文件的<bean>中添加<constructor-arg name="xxx" ref="……">注意:两种注入方式都需要注入的成员名称与配置文件中的bean中的name一致
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
Bean配置项
id:唯一标识class:具体类(必须配置)scope:范围 ,作用域constructor arguments:构造器的参数--构造器注入properties:属性--设值注入Autowiring mode:自动装配模式lazy-initialization mode:懒加载模式initialization/destruction method:初始化/销毁的方法
Bean的作用域:
1.singleton:单例,指一个bean容器中只存在一份(默认模式) 2.prototype:(一个bean容器中)每次请求(每次使用)都创建新的实例,destroy方式不生效 3.request:每次http请求创建一个实例且仅在当前request内有效 4.session:同上,每次http请求创建,当前session内有效 5.global session:基于portlet的web中有效(portlet定义了global session),如果是在web中,同session生命周期:定义,初始化,使用,销毁
Bean的生命周期:配置全局默认初始化、销毁方法。当同时配置,执行优先级:实现接口→<bean>标签的局部属性→<beans>的全局属性一.初始化:
1.实现org.springframework.beans.foctory.InitializingBean接口,覆盖afterPropertiesSet方法。系统会自动查找afterPropertiesSet方法,执行其中的初始化操作2.配置init-method例如设置bean中init-method="init"那么在初始化过程中就会调用相应class指定类的init()方法进行初始化工作1.实现org.springframework.beans.foctory.DisposableBean接口,覆盖destory方法。2.配置destory-method
<bean id="beanLifeCycle" class="com.imooc.lifecycle.BeanLifeCycle" init-method="start" destroy-method="stop"></bean>
二 销毁(与初始化类似)三 配置全局初始化、销毁方法(属于默认配置,参考截图)
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
注意:1,当三种方式同时使用时,全局(默认的)初始化销毁方法会被覆盖。2,另外实现接口的初始化/销毁方式会先于配置文件中的初始化/销毁方式执行。3,即使没有以上三种初始化方法也是可以编译执行的4、如果配置全局初始化、销毁,但没有写对应方法,则可通过编译;如果在<bean>标签中配置初始化、销毁,但没有写对应方法,则报错。==============================================================================================
xxxxAware接口
Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后可以获取相应资源 .通过Aware接口,可以对Spring相应资源进行操作(一定要慎重) ApplicationContextAware和BeanNameAware接口首选要配置bean标签 实现了ApplicationContextAware接口得到的ApplicationContext对象是一个容器,获取的bean的实例对象与IOC容器得到的是一样的; 实现了BeanNameAware接口可以获取到当前类对应的bean标签中配置的id属性值Bean的自动装配(Autowiring)
1.No:不做任何操作 2.byname:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配 3.byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生 4.Constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常Bean的自动装配:在beans标签配置属性 default-autowire="no/byName/byType/constructor" 作用为:省去了在Spring的xml中配置property标签和constructor-arg标签,只需要配置bean标签即可 PS:byName和byType为设值注入,constructor为构造注入;byName要求bean标签的id属性需要和成员变量的名称一致,byType和constructor则跟id无关Resource针对于资源文件的统一接口:
1.通过实现 ApplicationContextAware接口获得ApplicationContext对象, 2.而ApplicationContext对象的getResource方法可以得到Resource对象,getResource(String)方法参数前缀如下:-UrlResource:URL对应的资源,根据一个URL地址即可重建 -ClassPathResource:获取类路径下的资源文件 -FileSystemResource:获取文件系统里面的资源 -ServletContextResource:ServletContext封装的资源,用于方位2.ServletContext环境下的资源 -InputStreamResource:针对于输入流封装的资源 -ByteArrayResource:针对用于字节数组封装的资源3.ResourceLoader接口
所有的applicationcontext都实现了该接口,所以都能获取resource实例, Resorce template=ctx.getResourse( "classpath:com/myapp/config.xml");(1)classpath:com/myapp/config.xml 从classpath加载 (2)file:/data/config.xml 从文件系统中通过URL加载 (3)http:/myserver/logo.png 从URL加载 (4)/data/config.xml 依赖于ApplicationContextBean管理的注解:
使用过滤器进行自定义扫描: 默认情况下,类被自动发现并注册bean的条件是: 使用@Component,@Repository,@Service,@Controller注解或者使用@Component的自定义注解。 还可使用use-default-filters = "false"禁用自动发现与注册。 type="regex" 代表的是使用通配符的方式去匹配 type="annotation" 代表的是只匹配注解
注意:1,当三种方式同时使用时,全局(默认的)初始化销毁方法会被覆盖。2,另外实现接口的初始化/销毁方式会先于配置文件中的初始化/销毁方式执行。3,即使没有以上三种初始化方法也是可以编译执行的4、如果配置全局初始化、销毁,但没有写对应方法,则可通过编译;如果在<bean>标签中配置初始化、销毁,但没有写对应方法,则报错。==============================================================================================
xxxxAware接口
Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后可以获取相应资源 .通过Aware接口,可以对Spring相应资源进行操作(一定要慎重) ApplicationContextAware和BeanNameAware接口首选要配置bean标签 实现了ApplicationContextAware接口得到的ApplicationContext对象是一个容器,获取的bean的实例对象与IOC容器得到的是一样的; 实现了BeanNameAware接口可以获取到当前类对应的bean标签中配置的id属性值Bean的自动装配(Autowiring)
1.No:不做任何操作 2.byname:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配 3.byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生 4.Constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常Bean的自动装配:在beans标签配置属性 default-autowire="no/byName/byType/constructor" 作用为:省去了在Spring的xml中配置property标签和constructor-arg标签,只需要配置bean标签即可 PS:byName和byType为设值注入,constructor为构造注入;byName要求bean标签的id属性需要和成员变量的名称一致,byType和constructor则跟id无关Resource针对于资源文件的统一接口:
1.通过实现 ApplicationContextAware接口获得ApplicationContext对象, 2.而ApplicationContext对象的getResource方法可以得到Resource对象,getResource(String)方法参数前缀如下:-UrlResource:URL对应的资源,根据一个URL地址即可重建 -ClassPathResource:获取类路径下的资源文件 -FileSystemResource:获取文件系统里面的资源 -ServletContextResource:ServletContext封装的资源,用于方位2.ServletContext环境下的资源 -InputStreamResource:针对于输入流封装的资源 -ByteArrayResource:针对用于字节数组封装的资源3.ResourceLoader接口
所有的applicationcontext都实现了该接口,所以都能获取resource实例, Resorce template=ctx.getResourse( "classpath:com/myapp/config.xml");(1)classpath:com/myapp/config.xml 从classpath加载 (2)file:/data/config.xml 从文件系统中通过URL加载 (3)http:/myserver/logo.png 从URL加载 (4)/data/config.xml 依赖于ApplicationContextBean管理的注解:
使用过滤器进行自定义扫描: 默认情况下,类被自动发现并注册bean的条件是: 使用@Component,@Repository,@Service,@Controller注解或者使用@Component的自定义注解。 还可使用use-default-filters = "false"禁用自动发现与注册。 type="regex" 代表的是使用通配符的方式去匹配 type="annotation" 代表的是只匹配注解
=========================================================
.如果希望数组有序,可以让bean实现org.springframework.core.Ordered接口或使用的@Order注解.AutoWired注解
1、@Required注解适用于bean属性的setter方法
仅仅表示受影响的bean属性必须在配置时呗填充,通过bean定义或通过自动装配一个明确的属性值2、@Autowired注解为传统的setter方法、
a、可用于构造器或成员变量 b、默认情况下如果因找不到合适的bean将会导致Autowiring失败抛出异常,可以通过@Autowired(required=false)来避免 c、每个类只能有一个构造器被标记为(required=true)@Autowired的必要属性建议用@required注解
@Autowired注解标注的List和Map:
spring会将@Component注解标注的实现了BeanInterface的Bean的实例加载进去 @Order排序注解只对List有效,对Map无效@Autowired更新的用法
.可以通过添加注解给需要该类的数组的字段或方法,以提供ApplicationContext中的所有特定类型的bean .可以用于装配Key为String的Map:Map<bean ID,bean实例> List<bean 实例>
@Autowired private List<BeanInterface> list;//将接口BeanInterface的子类都存入List,子类使用@Order(1)进行排序 @Autowired private Map<String, BeanInterface> map;//将接口BeanInterface的子类都存入Map
使用@Autowired注意的事项
.@Autowired是由Spring BeanPostProcessor处理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型应用这些注解,这些类必须通过XML或者Spring的@Bean注解加载@Autowired
.可以使用@Autowired注解那些众所周知的解析依赖性接口,比如:BeanFactory,ApplicationContext,Environment,ResouceLoader,ApplicationEventPublisher,and MessageSouce@Autowired private ApplicationContext context
@Qualifier注解:
按类型自动装配可能多个bean实例的概况,可以使用@Qualifier注解缩小范围(或唯一指定), 也可以用于指定单独的构造器参数或方法参数 可用于注解集合类型变量. @autowired适用于字段,构造器,多参数的方法等这些允许参数级别使用@Qulifier注解缩小范围的情况. @Resource适用于成员变量,只有一个参数的setter方法.和集合List,map 所以在目标是构造器或一个多参数方法时,最好的方式时使用qulifier@qulifier注解最常用的方法:
@Autowired @Qualifier("main") private MovieCatalog movieCatalog; xml配置: <bean class="example.SimpleMovieCatalog"> <qualifier value="main"/> </bean>@Autowired与@Resource不同点
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
public class TestServiceImpl { @Autowired @Qualifier("userDao") private UserDao userDao; }
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
=============================================================================public class TestServiceImpl { // 下面两种@Resource只要使用一种即可 @Resource(name="userDao") private UserDao userDao; // 用于字段上 @Resource(name="userDao") public void setUserDao(UserDao userDao) { // 用于属性的setter方法上 this.userDao = userDao; } }
@Bean注解
@Bean如果没有指定name属性,则beanName默认为@Bean注解的方法的名称,指定name属性:@Bean(name="名称") 还可以指定@Bean(name="名称",initMethod="初始化方法",destroyMethod="销毁方法"),初始化方法和销毁方法需要定义在该bean指向的类中1.@Bean标识一个用于配置和初始化一个由SpringIoC容器管理的新对象的方法,类似于XML配置文件的<bean/> 2.可以在Spring的@Comonent注解的类中使用@Bean注解任何方法(仅仅是可以) 3.上一点中,通常使用的是@Configuration 例子: @Configuration public class AppConfig {//使用Configuration注解,相当于声明这个class为配置文件 @Bean public MyService myService() { return new MyServiceImpl(); //返回一个MyServiceImpl类的一个对象 } }==================================================================================
@Resource注解:
类似于@Autowired注解 Spring还支持使用JSR-250标准,@Resource注解的成员变量或setter方法,这是一种在Java EE 5和6的通用模式,Spring管理的对象也支持这种模式 @Resource有一个name属性,并且默认Spring解释该属性值作为被注入bean的名称,如果没有显式的指定@Resource的name属性,则默认的名称是从成员变量(@Resouce注解成员变量)或者setter方法(@Resource注解setter方法)得到; PS:注解提供的名字被解析为一个bean的名称,这个过程是由ApplicationContext中的CommonAnnotationBeanPostProcessor发现并处理的@PostConstruct注解:
注解初始化方法,类似于XML中配置的init-Method@PreDestroy注解:
注解销毁方法,类似于XML中配置的destroy-Method@Inject注解等效于@Autowired注解,可以使用于类、属性、方法、构造器
如果想使用特定名称进行依赖注入,使用@Named注解,@Named注解与@Component注解是等效的
==================================================================================
AOP:Aspect Oriented Programming的缩写
意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术; 主要用于:日志记录、性能统计、安全控制、事务处理、异常处理等
AOP的实现方式:
1、预编译 -AspectJ; 2、运行期动态代理(JDK动态代理、CGLib动态代理) -SpringAOP、JbossAOPAOP几个相关概念:
1.切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象 2.连接点(Joinpoint):程序执行过程中的某个特定的点 3.通知(Advice):在切面的某个特定的连接点上执行的动作 4.切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联 5.引入(Introduction):在不修改类代码的前提下,为类添加新的方法和属性 6.目标对象(Target Object):被一个或者多个切面所通知的对象 7.AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能) 8.织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个通知的对象 分为编译时织入,类加载时织入,运行时织入Advice(通知)类型:
1.前置通知(Before advice):在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出一个异常) 2.返回后通知(After returning advice):在某个连接点(join point)正常完成后执行的通知 3.抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知 4.后通知(After(finally) advice):在某个连接点退出的时候执行的通知(不论是正常返回还是异常退出) 5.环绕通知(Around Advice):包围一个连接点(join point)的通知Spring框架中的AOP的用途:
1.提供了声明式的企业服务,特别是EJB的替代服务的声明 2.允许用户定制自己的方面,已完成OOP与AOP的互补使用 Spring AOP的实现有两种: 1.有接口:Spring AOP默认使用标准的JavaSE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理 2.无接口:Spring AOP中也可使用CGLIB代理(如果一个业务对象并没有实现一个接口)基于xml配置的AOP
Spring所有的切面和通知器都必须放在一个<aop:config>内; 可以配置多个<aop:config>元素,每一个<aop:config>可以包含pointcut,advisor和aspect元素,且必须按照这个顺序来声明; <aop:config>风格的配置大量的使用了Spring的自动代理机制
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
advice的4种类型:1.before执行切入点之前执行 2.after-returning 切入点执行后执行 3.after-throwing 执行切入点发生异常时执行 4.after 最后必须执行的一个函数,相当于finally
Introductions Advice简介通知。
简介通知的主要配置是:声明一个接口A,再声明一个实现接口A的实现类B,并且用types-matching指定当前的这个简介通知所关联的业务类。然后通过implement-interface属性把接口A强制作为这些业务类的父类。在单元测试中,用getBean(beanId)方法得到业务类,然后把这个业务类强制转换成接口A类型,然后调用接口A的实现类B的方法。简介通知的用途我认为是:在业务逻辑操作中将横向的执行顺序改变为纵向的处理日志,事务相关的服务,通过类B实现这些服务的具体实现 —————————————————————————— 总结:通过配置《aop:declare-parents 》中的三个属性,分别指定了一个切入点匹配,一个接口,以及一个接口的默认的实现。如果这个对象满足了切入点表达式,不管它是什么类型,都可以将其强制转化为declare-parents 配置中指定的接口,以及给付给这个接口默认的实现。======================================================================================advisor就像一个小的自包含的方面,只有一个advice
切面自身通过一个bean表示,并且必须实现某个advice接口,同时,advisor也可以很好的利用AspectJ的切入表达式 Spring通过配置文件中<aop:advisor>元素支持advisor实际使用中,大多数情况下它会和transactional advice配合使用 为了定义一个advisor的优先级以便让advice可以有序,可以使用order属性来定义advisor的顺序 advisors的使用场景: 通常会用在一个环绕通知中 我们可以统计方法的调用次数或者调用频率,或是某种情况下需要对调用次数进行控制。 比如这里我们可以在函数尝试调用4次的时候抛出一个异常实现