spring 基础上

spring 是一个为解决企业应用开发复杂性而创建的开源框架,是一个轻量级的控制反转(IOC)和面向切向(AOP)的容器框架。
IOC(配置、注解)  Bean(配置、注解):在Spring里把由他管理的东西都叫Bean         AOP(配置、注解、AspectJ、API)
一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
- 从大小与开销都是轻量级的   - 通过控制反转的技术达到松耦合的目的   - 提供丰富的面向切面编程,允许通过分离应用的业务逻辑与系统级服务进行内聚性开发    - 包含并管理应用对象的配置和声明周期,这个意义上是一种容器    - 将简单的组件配置、组合成为复杂的应用,这个意义上是框架
适用范围:
构建企业应用(SSH springmvc spring hibernate/ibatis)单独使用Bean容器(Bean管理)
单独AOP进行切面处理 其他Spring功能,如:对消息的支持等    在互联网中的应用
Ioc 和 Aop 的容器 框架       简单 方便 快捷  spring带来了复杂javaEE的春天
spring的作用:
1.容器2.提供多种技术的支持如--JMS--MQ支持--UnitTest--...3.AOP(事务、日志等)4.提供了众多方便应用的辅助类(JDBC Template等)5.对主流应用框架(Hibernate等)提供了良好的支持
  框架的特点:
- 半成品- 封装了特定的处理流程和控制逻辑- 成熟的、不断升级改进的软件
  框架与类库的区别
- 框架一般是封装了逻辑、高内聚的,类库则是松散的工具组合- 框架专注于某一领域,类库则是更通用的
为什么使用框架?
软件系统日趋复杂,重用度高,开发效率和质量提高,软件设计人员要专注于对领域的了解,使需求分析更充分。易于上手,快速解决问题。
面向接口编程:
结构设计中,分清层次及调用关系,每层只向外(上层)提供一组功能接口,各层间仅依赖接口而非实现类
接口实现的变动不影响各层间的调用,这一点在公共服务中尤为重要
面向接口编程中的接口是用于隐藏具体实现和实现多态性的组件
IOC控制反转:控制权的转移,应用程序本身不负责所依赖对象的创建和维护,而是由外部容器负责创建和维护。
实现方式 DI依赖注入:是IOC的一种实现方式,在程序运行期间将所需的依赖对象注入、组装进去(考虑bean之间的相互组装和@Autowired)
例子:买房子(由开发商设计图纸,造房子,我们只负责使用)
Bean容器初始化
基础:两个包
 - org.springframework.beans
 - org.springframework.context
 - BeanFacoty提供配置结构和基本功能,加载并初始化Bean
 - ApplicationContext保存了Bean对象并在Spring中被广泛使用
方式,ApplicationContext
 - 本地文件 - Classpath - Web应用中依赖Servlet或Listener
文件(本地绝对路径加载):FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("f:/worksspace/appcontext.xml");
Classpath(相对路径):ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
web应用(利用servlet):
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  <servlet>
     <servlet-name>context</servlet-name>
     <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
     <load-on-startup>1<load-on-startup>
   </servlet>
单元测试:下载junit-*.jar并引入工程,创建UnitTestBase类,完成对Spring配置文件的加载,销毁,所有的单元测试类都继承自UnitTestBase,通过它的getBean方法获取想要得到的对象。子类(具体执行单元测试的类)加注解:@RunWith(BlockJUnit4ClassRunner.Class)。单元测试方法加注解:@Test。右键选择要执行的单元测试方法执行或者执行一个类的全部单元测试方法。
1注解@before,@after分别在@test执行之前和之后执行;2每执行一次@test,都会同样执行一次@before,@after;
在IOC容器中,把所有的对象都称为bean。Spring对于bean有两种使用方式:xml和注解。 
spring的注入方式:设值注入,构造注入。设值注入配置:<bean id="injectionService"class="com.imoc.ioc.injectionService.InjectionServiceImpl">
<property name="injectionDAO" ref="injectionDAO"></bean>
构造注入:
<bean id="injectionService"class="com.imoc.ioc.injectionService.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"></bean>
Spring IOC是一种设计模式,使对象不用显示的创建依赖对象,而是将对象创建的过程交给Spring的IOC容器去管理,通过依赖注入的方式,来实现IOC;
依赖注入的方式有两种:
1、设值注入:即通过XML中配置bean的依赖类,通过层级property属性,来配置依赖关系,然后Spring通过setter方法,来实现依赖类的注入;
声明两个bean,然后在IOC容器初始化加载当前XML配置文件的时候,去创建这两个对象。
property是属性的意思,也就是说在InjectionServiceImpl这个类里面,会有一个名为injectionDAO的成员变量,而它又是InjectionDAOImpl这个类型的。
ref表示引用id,它指向下面的injectionDAO,而injectionDAO又代表着InjectionDAOImpl的一个实例,所以就是把这个实例赋值给name为injectionDAO的成员变量。
在InjectionServiceImpl里要生成InjectionDAO的set方法。
2、构造器注入:方法同设值注入,不过具体实现的方法是通过显示的创造一个构造方法,构造方法的参数名称要与XML中配置的name名称一致,XML配置的标签为constructor-arg
不用再通过new创建对象 也就是不用静态加载 
Id:Bean的唯一标识;
Class:要进行实例化的类;
Scope:Bean的作用域;
Constructor arguments:注入方式中的构造器注入方式;
Properties:注入方式中的设值注入方式;
Autowiring mode:自动装配加载模式;
lazy-initialization mode:懒加载模式;
Initialization/destruction method:初始化和销毁方法。
bean作用域范围是指在同一个Ioc容器中。
singleton:在一个bean容器中只有一份。(一个bean容器是指启动时加载一次xxx.xml文件)。在不同的容器中示例不同(容器不同)。同一个容器中相同(singleton模式)
prototype:每次请求(每次使用)创建新的实例。destroy方式不生效。不同的容器中不同(容器不同),相同的容器中不同(prototype模式)
request:每次http请求创建一个实例且在当前request内有效
session:同上,每次http请求创建,当前session内有效
global session:基于portlet的web中有效(portlet定义了global session),如果是在web中,同session
这种init-method及destroy-method方法是spring容器初始化bean和销毁前所做的操作。
关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:
第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作;
第二种是:通过 在xml中定义init-method 和  destory-method方法;
第三种是: 通过bean实现InitializingBean和 DisposableBean接口。
Bean的生命周期:
定义(xml配置)-> 初始化 -> 使用 -> 销毁
关于bean初始化和销毁:
1,默认全局的初始化和销毁方法;
 在xml文件中的<breans>标签中配置全局默认初始化和销毁方法,并在相应的bean类中增加相应方法。
 <beans>中配置的所有bean,在类中,或相应的bean标签中未设置初始化和销毁方法的情况下会默认执行以上全局方法
 <beans default-init-method="defaultInit" default-destroy-method="defaultDestroy" ></beans>
2,实现接口的初始化(InitializingBean)和销毁(DisposableBean)方法;
 初始化:实现org.springframework.beans.factory.InitializingBean接口,并重写afterPropertiesSet();
 销毁:实现org.springframework.beans.factory.DisposableBean接口,并重写destroy();
3,配置文件中配置初始化(init-method="initMethodName")和销毁()方法;
初始化:
1.xml中配置:<bean id="exampleInitBean" class="example.ExampleBean" init-method="init" ></bean>
2.在ExampleBean类中添加init()
销毁:
1.xml中配置:<bean id="exampleInitBean" class="example.ExampleBean" destroy-method="destroy" ></bean>
2.在ExampleBean类中添加destroy()
这三个方法同时使用时
1.如果类中或相应bean标签有相应初始化及销毁配置,则默认的不再执行。
2.类中或相应bean标签中都设置了,则相应配置的方法都执行。
3.类中对应的方法优先于bean标签中配置的方法执行。
4.默认的配置可以有可以没有,如果有默认配置但没有相应方法,也不会报错。
启动Ioc容器,实例化ApplicationContext上下文实例,然后加载配置文件,在应用第一次使用或者通过getBean()获取对象时,初始化相应的bean。在初始化bean的过程中先判断是否实现了Aware系列接口,InitializationBean接口(bean生命周期之创建),DiapostionBean接口(bean生命周期之销毁),实现了则进行相应的资源注入,接口方法调用等。这些接口实现之后,覆盖接口中的方法都是在bean初始化过程中自动调用,没有显式调用。
值得注意:Ioc容器和上下文的初始化一般不包括bean的依赖注入的实现。有一个例外,在使用Ioc容器时有一个预实例化配置,当bean配置了该属性lazyinit时,bean的初始化和Ioc容器的初始化一起完成。

1.ApplicationContextAware
1.1  接口方法:setApplicationContext
1.2  作用:通常用来获取上下文对象,声明全局变量后在方法中对变量进行初始化并供其他方法调用
1.3  实现过程:创建一个类并实现ApplicationContextAware接口,重写接口方法public void setApplicationContext(ApplicationContext applicationContext);在xml文件中配置该类;当spring加载该配置文件时即调用接口方法

2.BeanNameAware
2.1  接口方法:setBeanName
2.2  作用:获取声明的类名,声明全局变量后在方法中对变量进行初始化并供其他方法调用
2.3  实现过程:创建一个类并实现BeanNameAware接口,重写接口方法public void setBeanName(String name);在xml文件中配置该类;当spring加载该配置文件时即调用接口方法

综合测试:
1.创建一个类,同时实现ApplicationContextAware和BeanNameAware接口并重写其方法。声明一个全局变量beanName并在方法setBeanName对其初始化;
2.在setApplicationContext方法中使用参数applicationContext的getBean方法(方法参数为成员变量beanName,即this.beanName)获取bean的名称并打印其hashcode
3.将1中创建的类配置到xml文件中
4.创建单元测试,读取xml文件并执行测试方法,通过上下文信息直接获取bean并打印出其hashcode
结论:在加载xml文件时即加载其配置的bean并调用其中的方法,最后的hashcode相同,说明获取的bean是同一个。

  <!-- 讲述了自动装配autowiring,有三种:byName,byType,constructor -->
        <!-- 首先在xml的 beans 中添加全局配置设置为default-autowire="constructor" -->
        <!-- byName要求xml文件bean中的id,要与Javabean中的变量名相同(严格来说,是与setXxx方法中Xxx首字母小写后相同) -->
        <!-- byType要求set方法中形参的类型,要与xml文件bean中的class相匹配 -->
        <!-- constructor要求Javabean中构造方法的形参类型要与xml文件bean中的class相匹配 -->
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无关

Resources (针对于资源文件的统一接口)

- UrlResource:URL 对应的资源,根据一个 URL 地址即可获取
- ClassPathResource:获取类路径下的资源
- FileSystemResource:获取文件系统里面的资源
- ServletContextResource:ServletContext 封装的资源,用于访问 ServletContext 环境下的资源
- InputStreamResource:获取输入流封装的资源
- ByteArrayResource:获取字节数组封装的资源

ResourceLoader: 所有的 application contexts 都实现了 ResourceLoader 接口,因此所有的 application contexts 都能获取Resource实例
通过实现 ApplicationContextAware 接口中的方法 
setApplicationContext(ApplicationContext applicationContext)
Resource resource = applicationContext.getResource("xxx");
1.在spring规定中,resources文件夹是访问资源的入口。
2.classPath:xxx/src/main
3.getResources()方法的参数:classPath方式: classPath:xxx.txt
4.file方式: file:D:\\...\\xxx.txt
5.url方式: url:http://.../.../xxx
6.没有前缀时依赖applicationContext的配置文件路径:即使用配置文件的路径
Bean 的定义及作用域注解
A、@Controller :注解控制器类(控制层 MVC)
B、@Service :注解服务类(服务层)
C、@Repository :注解 DAO 类(持久层)
D、@Component :将普通的 bean 注解到 spring 容器中,相当于配置文件中的<bean id="xxx" class="xxx"/>
元注解(Meta-annotations)
元注解即是许多 Spring 提供的注解可以作为自己的代码,元注解是一个简单的注解,可以应用到另一个注解
除了 value() 元注解还可以有其他的属性,允许定制
类的自动监测及 Bean 的注册
Spring 可以自动检测类并注册 Bean 到 Applicationcontext 中
<context:annotation-config />
通过基于 xml 的 Spring 配置
为了能够自动检测到这些类并注册相应的 Bean ,需要
<context:component-scan base-package="xxx" />
<context:component-scan> 包含 <context:annotation-config>,通常使用前者后,就不需要再使用后者
使用过滤器进行自定义扫描
A、默认情况下,类被自动发现并注册 bean 的条件:使用 @Component @Repository @Service @controller 注解或者使用 @Component 的自定义注解
B、可以通过过滤器修改默认注解的行为
C、还可以使用 use-default-filters = "false" 禁用自动发现与注册
@AutoWired用处广,意思为自动注入bean 可用在  构造器  set方法  成员变量上
 @Autowired
    private InjectionDAO injectionDAO;
    //@Autowired
    public void setInjectionDAO(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }
    //@Autowired
    public InjectionServiceImpl(InjectionDAO injectionDAO) {
        this.injectionDAO = injectionDAO;
    }
上述这种情况是不允许的,但是允许set和构造器其中一个被autowired
在Service中使用DAO对象的时候,加上Autowired注解,不需要在xml中配置,也不需要setter方法
  @Autowired
  private InjectionDAO injectionDAO;
@Autowired注解:
1.@Autowired注解可以用到spring特殊的接口上:
eg:
@Autowired
ApplicationContext ac;
2.@Autowired可以用到数组注解上,数组的字段或者方法需要的特定类型的bean,将ApplicationContext中该类型的所有bean配装到改数组上。(数组-set,map)
map的键存储bean的id,值存储bean。key是String。
@Autowired注解用在数组类型上时,将ApplicationContext里面注册的所有该类型的bean装配到数组上。当希望装配有序时,可以利用@Order注解进行注解
eg:
@Order(value=1)(该数值是整型)
@Autowired
注意:@Order注解只对数组有序有效。例如map无效
按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数
可用于注解集合类型变量
如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术上能够通过@Qualifier指定bean的名字),替代方式是使用JSR-250@Resource注解,他是通过其独特的名称来定义识别特定的目标(这是一个与所声明的类型是无关的匹配过程)
因语义差异,集合或Map类型的bean无法通过@Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@Resource注解,通过唯一名称引用集合或Map的bean
@Autowired适用于fields,constructors,multi-arguement methods这些允许在参数级别使用@Qualifier注解缩小范围的情况
@Resource适用于成员变量、只有一个参数的setter方法,所以在目标是构造器或一个多参数方法时,最好的方式时使用qualifiers
JSR-250标准注解,推荐使用@Resource来代替Spring专有的@Autowired注解。只不过@Autowired按byType自动注入,而@Resource默认按byName自动注入罢了。@Resource有两个属性是比较重要的,分别是name和type,Spring将 @Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略
@Qualifier注解:<br>
按类型自动装配可能有多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围或者指定唯一,也可以用于指定单独的构造器参数或方法参数,也可用于注解集合类型变量;
用法如下:
如果使用bean装配则不需要再Spring XML中配置,直接在bean类中使用 @Qualifier("beanName")
如果需要在Spring XML中配置,则在bean标签下添加<qualifier value="名称"></qualifier>,然后在bean类中使用@Qualifier("名称")
虽然@Resource和@Autowired都可以来完成注入依赖,但它们之间是有区 别的。首先来看一下:
 a。@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入;
 b。@Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;
 c。@Resource注解是又J2EE提供,而@Autowired是由spring提供,故减少系统对spring的依赖建议使用  
       @Resource的方式;
使用Bean注解
在xml中配置了使用注解的方式加载类
定义@Configuration注解的类在类中实现
@Configuration
public class StoreConfig {
  @Bean("store")
  public Store getStore(){
    return new StringStore();
  }
}
则context会自动识别到configuration,并识别bean的注解,相当于在xml中配置<bean>
之后可以直接用过context.getBean()获取这个bean
基于java的容器注解:
1.@Bean:初始化一个bean并注册到springIoc容器加以管理。
同xxx.xml配置文件中的<bean>,适用于成员方法上,结合@Configuration(类上)使用
2.@Bean注解初始化生成的bean,在不指定名称时,是该注解注解的成员方法的名字
eg:
@Bean
public A getA(){return new A();}//该bean在注册到SpringIoc容器里的名称是getA.
指定名称@Bean(name="xx")时,该bean在注册到SpringIoc容器里的名称是xx
3.@Bean(name="" initMethod="" destroyMethod=""),支持init和destroy,同xxx.xml配置文件效果相同。
property文件是key-value键值对形式的文件,
加载资源文件:
<context:property-placeholder location="classpath:/com/acme/jdbc.propertied"/>
加载这个文件后,可以再当前文件中采用${jdbc.url}这种形式来使用配置文件中的内容.
例如:
<property name="url" value="${jdbc.url}"/>
如果使用注解则:
在类名前加上:
@Configuration
@ImportResource("classpath:/com/acme/propertied-config.xml")引入一个资源,对应一个xml文件中包含property_placeholder
在配置文件中使用username的时候需要注意:username输出有时会是登录用户的username,所以一般在配置文件中配置例如jdbc.username的形式以防止混淆.
加载properties文件中的键值

在xml文件中配置使得可以识别注解Configuration
在Configuration中使用注解ImportResource("...") 引入一个xml文件,并对每一个对象使用@Value("${....}")引入对应properties文件中的键值
@Configuration
@ImportResource("com/beanannotation/javabased/config.xml")
public class StoreConfig {
  @Value("${url}")
  String url;
  @Value("${jdbc.username}")
  String username;
  @Value("${password}")
  String password;
  @Bean("myDirverManager")
  public MyDriverManager myDriverManager(){
    return new MyDriverManager(url, username, password);
  }
}

在ImprotResource文件中使用
<context:property-placeholder location="com/beanannotation/javabased/config.properties"></context:property-placeholder>
通过location引入对应的properties文件

@Bean和@Scope
@Bean默认:是单例的
@Scope注解:指定范围,singleton,prototype(每次请求都会创建一个新的对象,为了区分,应该查看对象的hashcode,而类的hashcode是一样的),
采用哪种代理方式proxyMode
CustomAutowireConfigurer注解
1、CustomAutowireConfigurer:继承了BeanFactoryPostProcessor,它使自定义的自动绑定qualifier类型的注册更便利。. 
2、AutowireCandidateResolver:策略接口,对特定的依赖,这个接口决定一个特定的bean definition是否满足作为自动绑定的备选项。
基于泛型的自动装配:
1、在实例类中要要定义好泛型。
2、在需要自动装配的地方写明需要的泛型类型,会自动将符合泛型类型的实例装配好的。
3、@bean注解写在方法上的时候要注意返回类型是否重复了,否则会报错
@TestJavaBased.java
@RunWith(BlockJUnit4ClassRunner.class)
public class TestJavaBased extends UnitTestBase{
	public TestJavaBased(){
		super("classpath*:spring-beanannotation.xml");
	}
@Test
	public void testG(){
		StringStore store=super.getBean("stringStoreTest");
	}
}

@Store.java
package com.imooc.annotation.javabased;
public interface Store<T> {
}

@StringStore.java
package com.imooc.annotation.javabased;
public class StringStore implements Store<String> {
}

@IntegerStore.java
package com.imooc.annotation.javabased;
public class IntegerStore implements Store<Integer> {
}

@StoreConfig.java
package com.imooc.annotation.javabased;
@Configuration
public class StoreConfig {
@Autowired
	private Store<String> s1;

	@Autowired
	private Store<Integer> s2;
	
	@Bean
	public StringStore stringStore(){
		return new StringStore();
	}
	
	@Bean
	public IntegerStore integerStore(){
		return new IntegerStore();
	}
	
	@Bean(name="stringStoreTest")
	public Store stringStoreTest(){//相当于xml:<bean id="stringStoreTest" class="com.imooc.annotation.javabased.Store" ></bean>
		syso("s1:"+s1.getClass().getName());
		syso("s2:"+s2.getClass().getName());
		return new IntegerStore();
	}
}

@spring-beanannotation.xml
<context:component-scan base-package="com.imooc.annotation" ></context:component>

@Resource注解:
1.用于成员变量或setter方法。有属性name默认为bean的名称。即
@Resource(name="xxx").没有指出名称时,从属性名或setter方法得出:
@Resource
private A a;//a
@Resource
public void setA(A a){}//setA
解析bean名称的过程,是ApplicationContext的commonAnnotationBeanPostProcessor完成的,即commonAnnotationBeanPostProcessor能够识别@Resource注解
@PostConstruct 和 @PreDestory,使用的前提条件是CommonAnnotationBeanPostProcessor在Spring的ApplicationContext中注册了,才能使用
@Resource  通常用在成员变量或者set方法上.
注解提供的名字被解析成为一个bean的名称,这是由ApplicationContext的中的CommonAnnotationBeanPostProcessor提供的.
CommonAnnotationBeanPostProcessor不仅能识别@Resource  还在Spring2.5中引入支持初始化回调和销毁回调,前提是CommonAnnotationBeanPostProcessor是Spring的ApplicationContext中注册的
@Inject 等效于@Autowired, 可以使用于类,属性,方法,构造器
@Name 如果想使用特定名称进行依赖注入 使用@Named
@Named与@Component是等效的
@Named("movieLisner")

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lozhyf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值