Spring实战基础笔记

1. 什么是spring

spring是一个开源框架,致力于简化企业应用开发,主要通过基于POJO的轻量级和最小侵入性编程,通过依赖注入和面向接口编程实现松耦合,基于切面编程实现应用逻辑和系统服务分离形成可重用组件,通过切面和模板减少样板式代码。


2. bean的生命周期

       在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一实例,对单线程的程序来说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程同时存取共享资源所引发的数据不同步问题。
       然而在spring中 可以设定每次从BeanFactory或ApplicationContext指定别名并取得Bean时都产生一个新的实例
       在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的Bean时都会产生一个新的实例
       一个Bean从创建到销毁,如果是用BeanFactory来生成,管理Bean的话,会经历几个执行阶段(如图1.1):


1:Bean的建立:
       容器寻找Bean的定义信息并将其实例化。
2:属性注入:
       使用依赖注入,Spring按照Bean定义信息配置Bean所有属性
3:BeanNameAware的setBeanName():
       如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
4:BeanFactoryAware的setBeanFactory():
       如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
5:BeanPostProcessors的ProcessBeforeInitialization()
       如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用
6:initializingBean的afterPropertiesSet():
       如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法
7:Bean定义文件中定义init-method:
       可以在Bean定义文件中使用"init-method"属性设定方法名称例如:
       如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法
8:BeanPostProcessors的ProcessaAfterInitialization()
       如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法。此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉


1:DisposableBean的destroy()
       在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法
2:Bean定义文件中定义destroy-method
       在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称
       如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。


3.  Spring中ApplicationContext和beanfactory区别

       BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。 
       ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能: 
        • MessageSource, 提供国际化的消息访问  
        • 资源访问,如URL和文件  
        • 事件传播  
        • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层  
       1).BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。
       2).BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册

4. Spring的JDBC和DAO模块的好处

       使用jdbc编程通常会导致大量的样板式代码,例如获取数据库连接、创建语句、处理结果集到最后关闭数据库连接。spring的JDBC和DAO模块抽象了这些样板式代码,使我们的数据库代码变得简洁明了,还可以避免因为关闭数据库资源失败而引发的问题。该模块在多种数据库服务的错误信息之上构建了一个语义丰富的异常层,以后我们不需要解释那些隐晦专有的sql错误信息。

5. Spring装配机制

       1)在xml中进行显示配置
       2)在java中进行显示配置
       3)隐士的bean发现机制和自动装配机制

6. 自动化装配

方案一:
       1)组件扫描:spring会自动发现应用上下文中所创建的bean。例如使用@Component注解注释的bean。
<context:component-scan base-pacage="">
       2)自动装配:spring自动满足bean之间的依赖。使用@AutoWired注解
方案二:
       1)在类上添加注解@Configuration,表示此类是一个配置类
       2)在类上添加注解@ComponentScan,表示自动扫描配置,默认自动扫描该类所在的包中的类。可以设置扫描包
ComponentScan(basePackage={"one","two"})或者设置
ComponentScan(basePackageClasses{A.class,B.class})


7. 通过java代码装配bean

       1)在方法上添加@Bean注解,该方法会以方法名为bean的id
       2)该注解会自动装配参数中的bean

8. 通过xml装配bean

1)基本格式
<bean  id = ""  class="">
2)构造器初始化
<bean id ="" class ="">
    <constructor-arg ref=""/>
    <constructor-arg value=""/>
    <!-- 注入空值 -->
    <constructor-arg><null/></constructor-arg>     
    <!-- list集合-->   
    <constructor-arg> 
        <list> <value></value> </list> </constructor-arg> 
    <!-- set集合--> 
    <constructor-arg>
        <set>
            <ref bean=""/>
            <ref bean=""/>
        </set>
     </constructor-arg>
</bean>
3)属性注入
<bean id ="" class ="">
    <property name="" value=""/>    
    <property name="" ref=""/>  
    <!-- list集合-->   
    <property name=""> <list> <value></value> </list> </property> <!-- set集合--> 
        <property name="">
            <set>
                <ref bean=""/>
                <ref bean=""/>
            </set>
        </property>
</bean>

9. 导入和混合配置

       1)在类上添加注解@Import导入类@Import(One.class)    
       2)在类上添加注解@ImportResource(“”classpath:one.xml“”)     
       3)在xml中使用<import resource=""/>

10. profile解决跨环境加载不同配置

1)在类上配置
@Configuration
@Profile("dev")
public class DecelopmentProfileConfig{
    @Bean
    public DataSource dataSource(){
        return new DataSource();
    }
}
2)在方法上配置
@Configuration
public class DecelopmentProfileConfig{
    @Bean
    @Profile("dev")
    public DataSource dataSource(){ return new DataSource(); }
      
    @Bean
    @Profile("prod")
    public DataSource dataSource(){ return new DataSource(); }
}
3)在xml中配置
<beans prifile="dev">
</beans>
4)激活profile
spring确定哪个profile处于激活状态时,需要依赖两个独立属性:spring.profiles.active和spring.profile.default
方案一
在web.xml中配置参数
<conext-param>
    <param-name>spring.profiles.default</param-name>
    <param-value>dev</param-value>
</context-param>
<servlet>
    <servlet-name>servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>spring.profiles.default</param-name>
        <param-value>dev</param-value>
    </init-param>
</servlet>
方案二
使用注解@ActivitePrifile(“”)

11. @Conditional注解条件初始Bean

@Bean
@Conditional(MagicBeanCobdition.class)
public MagicBean magicBean(){
    return MagicBean();
}
public class  MagicBeanCondition implements Condition{
    public boolean matches(ConditionContext context){
        Environment env = context.getEnvironment();
        return env.containsProperty("magic");    
    }
}

12. 处理自动装配歧义

1)首选设置
注解@Primary或xml配置primary=“true”
2)限定符
使用注解@Qualifier("")
3)自定义限定符

13. bean的作用域

1)单例(Singleton)
2)原型(Prototype)
3)会话(Session)
4)请求(Request)
方式一:
       使用注解@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
方式二:
       在xml中配置scope=“prototype”

14. 面向切面编程

       在运行时动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面编程。
       在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

15. Aop术语

        通知:通知定义了切面是什么以及什么时候调用。通知主要分为:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
        连击点:应用执行过程中能够插入切面的一个点
        切点:通知定义了切面的什么和何时,切点定义了何处。切点的定义会匹配通知所要织入的一个或多个连接点
        切面:切面是通知和切点的结合。通知和切点共同定义了切面的全部内容——它是什么,在何时何处完成其功能。
        引入:允许我们向现有的类添加新方法和属性
        织入:把切面应用到目标对象并创建新的代理对象的过程。织入主要在编译期、类加载期和运行期。

16. spring对Aop的支持

       1)基于代理的经典Spring Aop
       2)纯POJO切面
       3)@AspectJ注解驱动的切面
       4)注入式AspectJ切面

17. 使用切面

1)定义切面
@Aspect
public class Audience{
       
    @Pointcut("execution(** concert.Performance.perform(..))")
    public void performance(){}
       
    @Before("performance()")
    public void takeSeates(){}


    @AfterReturning("execution(** concert.Performance.perform(..))")
    public void applause(){}
}
2)在java中启用AspectJ
@Configuration
@EnableAspectJAuroProxy
@ComponentScan
public class ConcertConfig{
        
    @Bean
    public Audience audience(){
        return new Audience();
    }
}
3)在xml中配置启用AspectJ
<aop:aspectJ-autoproxy>
<bean class="Audience">
4)在xml中声明切面
<aop:config>
    <aop:aspect ref="audience">
        <aop:pointcut id="performance" expression="execution(** concert.Performance.perform(..))"/>
        <aop:before pointcut-ref="performance" method=""> 
        <aop:after-returning pointcut="execution="** concert.Performance.performance(..)"    method="">
    </aop:aspect>
</aop:config>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值