2.使用spring管理bena
spring核心容器就是一个超级大工厂,所有的对象都会被当成spring核心容器管理的对象,spring把容器中的所有对象都称为bean。spring中的bean不同于java bean。java bean需要遵循一些特定的规范,在spring'中没有任何要求,只要是一个java类,spring就可以管理该java类。并将它当成bean处理。即一切对象都是bean
例子:
3.spring的核心机制:依赖注入
依赖:A对象需要调用B对象方法的情形,这样情形Spring称为依赖。
spring框架的两个核心功能:
第一:spring负责创建管理所有的java对象,这些java对象称为bean
第二:spring容器管理bean之间的依赖关系。spring使用依赖注入的方式来管理bean之间的依赖关系。(依赖注入和控制反转的意义是一样的)
使用spring框架以后,调用者无需主动获取依赖对象,而是被动接受spring容器为调用者的成员变量赋值即可。
依赖注入的方式:
设值注入:IOC容器使用成员变量的setter方法来注入依赖对象
构造注入:IOC容器使用构造器来注入依赖对象
4.spring容器的使用
spring容器有两个核心接口,BeanFactory和ApplicationContext,ApplicationContext是BeanFactory的子接口。spring配置文件通常需要使用Resource对象传入。大部分都不会使用BeanFactory实例作为spring容器,而是使用ApplicationContext作为容器,因此也把spring容器成为spring的上下文。,而且增强了BeanFactory的功能。
由于spring是面向接口编程的,不管是调用者还是被依赖对象,都应该定义为接口,程序应该面向他们的接口,而不是编程实现类。便于升级和维护上边的代码改写
4.BeanFactory和ApplicationContext有什么区别?
BeanFactory可以理解为含有bean集合的工厂类.BeanFactory包含了种bean的定义,以便在接收到客户端请求时将对应的
bean实例化.
BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。
BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。
从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。
但application context在此基础上还提供了其他的功能。
1、提供了支持国际化的文本消息
2、统一的资源文件读取方式
3、已在监听器中注册的bean的事件
以下是三种较常见的 ApplicationContext 实现方式:
1、ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义.应用程序上下文从程序环境变量中取得.
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
2、FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。
ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml");
3、XmlWebApplicationContext:由Web应用的XML文件读取上下文。
将Spring配置到应用开发中有以下三种方式:
1、基于XML的配置
2、基于注解的配置
3、基于Java的配置
在Spring框架中,依赖和服务需要在专门的配置文件来实现,我常用的XML格式的配置文件。
这些配置文件的格式通常用开头,然后一系列的bean定义和专门的应用配置选项组成。
SpringXML配置的主要目的时候是使所有的Spring组件都可以用xml文件的形式来进行配置。
这意味着不会出现其他的Spring配置类型(比如声明的方式或基于Java Class的配置方式)
Spring的XML配置方式是使用被Spring命名空间的所支持的一系列的XML标签来实现的。
Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。
<beans>
<!-- JSON Support -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>
下面这个web.xml仅仅配置了DispatcherServlet,这件最简单的配置便能满足应用程序配置运行时组件的需求。
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring对Java配置的支持是由@Configuration注解和@Bean注解来实现的。由@Bean注解的方法将会实例化、
配置和初始化一个新对象,这个对象将由Spring的IoC容器来管理。@Bean声明所起到的作用与 元素类似。
被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。被@Configuration声明的类可以
通过在同一个类的内部调用@bean方法来设置嵌入bean的依赖关系。
最简单的@Configuration 声明类请参考下面的代码:
@Configuration
public class AppConfig{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
对于上面的@Beans配置文件相同的XML配置文件如下:
<beans>
<bean id="myService" class="com.howtodoinjava.services.MyServiceImpl"/>
</beans>
上述配置方式的实例化方式如下:利用AnnotationConfigApplicationContext 类进行实例化
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
要使用组件组建扫描,仅需用@Configuration进行注解即可:
@Configuration
@ComponentScan(basePackages = "com.howtodoinjava")
public class AppConfig {
...
}
在上面的例子中,com.acme包首先会被扫到,然后再容器内查找被@Component 声明的类,
找到后将这些类按照Sring bean定义进行注册。
如果你要在你的web应用开发中选用上述的配置的方式的话,需要用AnnotationConfigWebApplicationContext类来读取配置文件,
可以用来配置Spring的Servlet监听器ContrextLoaderListener或者Spring MVC的DispatcherServlet。
<web-app>
<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified @Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.AppConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.web.MvcConfig</param-value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Spring在2.5版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代XML方式的bean描述,
可以将bean描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。
注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式。
如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
在context:annotation-config/标签配置完成以后,就可以用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。
下面是几种比较重要的注解类型:
1、@Required:该注解应用于设值方法。
2、@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。
3、@Qualifier:该注解和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义。
4、JSR-250 Annotations:Spring支持基于JSR-250注解的以下注解,@Resource、@PostConstruct和@PreDestroy。
Spring容器中的bean可以分为5个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:
1、singleton:每次请求该bean都将获得相同的实例容器负责跟踪bean实例的状态维护bean的生命周期。
2、prototype:程序每次请求该id的bean,spring都会新建一个bean实例,然后返回给程序。这种情况使用new关键字创建bean实例,一旦创建成功,容器不在跟踪实例
3、request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收.默认singleton
4、Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
5、global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。
如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。
全局作用域与Servlet中的session作用域效果相同。
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。
开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 <context:annotation-config/>元素。
这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException。
@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。
当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定需要装配的确切的bean。
Spring支持两种类型的事务管理:
面向切面的编程,或AOP, 是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
引入允许我们在已存在的类中增加新的方法和属性。
被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。
代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadata autoproxying
织入是将切面和到其他应用类型或对象连接或创建一个被通知对象的过程。
织入可以在编译时,加载时,或运行时完成。
在这种情况下,切面由常规类以及基于XML的配置实现。
在这种情况下(基于@AspectJ的实现),涉及到的切面声明的风格与带有java5标注的普通java类一致。