spring学习笔记

本贴最后更新于 3068 天前,其中的信息可能已经渤澥桑田

spring

spring 完全学习笔记

some concepts:

POJO:plain old java object,指既简单java对象,指不继承任何类(object外),实现任何接口,POJO是这样的一种“纯粹的”JavaBean,在它里面除了JavaBean规范的方法和属性没有别的东西,即private属性以及对这个属性方法的public的get和set方法。

Spring的目的

Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。然而,Spring并不想取代那些已有的框架,而是与它们无缝地整合。
Spring的主要目的是使JavaEE易用和促进好编程习惯。
Spring不重新开发已有的东西。因此,在Spring中你将发现没有日志记录的包,没有连接池,没有分布事务调度。这些均有开源项目提供(例如Commons Logging 用来做所有的日志输出,或Commons DBCP用来作数据连接池),或由你的应用程序服务器提供。因为同样的的原因,我们没有提供O/R mapping层,对此,已有友好的解决办法如Hibernate和JDO。Spring的目标是使已存在的技术更加易用。

Spring核心

1.bean的注册与创建

抽象bean接口

package com.learning.spring.assembly;
 
public interface CompactDisc {
  public void play();
}

1.1在xml中进行显示配置

xml文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ctx="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<ctx:component-scan base-package="com.learning.spring.assembly.*"/>
</beans>

XMLDisc(bean)

package com.learning.spring.assembly.xmlassembly;
 
import com.learning.spring.assembly.CompactDisc;
 
public class XMLDisc implements CompactDisc {
  private String title = "My song";
  private String albums = "from XML";
  public void play() {
    // TODO Auto-generated method stub
    System.out.println("Playing"+title+"  "+albums);
    }
  }

1.2使用基于注解的java config

DiscConfig(java 配置类)

package com.learning.spring.assembly.javaconfig;
 
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ComponentScan("com.learning.spring.asssembly.*")
public class DiscConfig {
}

ConfigDisc(bean)

package com.learning.spring.assembly.javaconfig;
 
import org.springframework.stereotype.Component;
 
import com.learning.spring.assembly.CompactDisc;
 
//显式声明bean的id
@Component("mysong")
public class ConfigDisc implements CompactDisc {
     private String title = "My song";
      private String albums = "from java config";
 
       public void play() {
             // TODO Auto-generated method stub
                  System.out.println("Playing"+title+"  "+albums);
             }
         }

2.Bean的注入

2.1AutoWired注解

1、@Required注解适用于bean属性的setter方法
仅仅表示受影响的bean属性必须在配置时呗填充,通过bean定义或通过自动装配一个明确的属性值
2、@Autowired注解为传统的setter方法 、 a、可用于构造器或成员变量
b、默认情况下如果因找不到合适的bean将会导致Autowiring失败抛出异常,可以通过@Autowired(required=false)来避免
c、每个类只能有一个构造器被标记为(required=true)
@Autowired的必要属性建议用@required注解
可以通过添加注解给需要该类型的数组的字段或方法,以提供ApplicatonContext中的所有特定类型的bean

@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalog){
this.movieCatalogs = movieCatalogs
}
也可以用于装配key为String的Map
@Autowired
public void setMovieCatalog(Map<String,MovieCatalog> movieCatalog) { this.movieCatalogs = movieCatalogs }
如果希望数组有序,可以让bean实现org.springframework.core.Ordered接口活着使用@Order注解
用于collection中,那么该context所有该类型都自动注入了,就是说autowired可以在集合类型中找出要自动注入的类型,会把所有可以注入进来的bean都注入进来。有一个特殊的地方是map的key只能是string的

PS:用@Autowired注解spring自己的解析依赖性接口, 可以不用使用aware接口去得到context了

@Qualifier:

按类型自动装配可能多个bean实例的概况,可以使用@Qualifier注解缩小范围 (或唯一指定), 也可以用于指定单独的构造器参数或方法参数 可用于注解集合类型变量.

@autowired适用于字段,构造器,多参数的方法等这些允许参数级别使用 @Qulifier注解缩小范围的情况.
@Resource适用于成员变量,只有一个参数的setter方法.

所以在目标是构造器或一个多参数方法时,最好的方式时使用qulifier

@qulifier注解最常用的方法:

@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;

xml配置:

<bean class="example.SimpleMovieCatalog">  
<qualifier value="main"/>
</bean>`

2.2借助javaconfig实现注入

Config文件

@Configuration
public class DiscConfig {
 
     @Bean(name="disc1")
      public CompactDisc configdisc(){
            return new ConfigDisc();
         }
 
 
     @Bean
     public DiscPlayer discplay(){
    //    实际上configdisc()的调用被拦截确保直接返回该方法创建的bean(类似单例),并不每次对其实际调用
                 return new DiscPlayer(configdisc());
              }
 
    @Bean
    public DiscPlayer discplay(CompactDisc cd){
                return new DiscPlayer(cd);
            //    实际推荐这种写法,因为方便理解,并且易于扩展与使用
              }
        }

DiscPlayer.java

        @Component
        public class DiscPlayer {
 
             private CompactDisc cd;
 
             @Autowired
             public DiscPlayer(CompactDisc cd){
                  this.cd=cd;
              }
 
              public void play(){
                   cd.play();
               }
          }

2.3运行时装入

2.3.1属性占位符

形式:${...}

<bean id="sgtPeppers"  
     class="soundsystem.blankdisc"  
     c:\_title="${disc.title}"  
     c:\_artilst="${disc.artilst}" />
 
 public BlankDisc(
   @Value("$disc.title") String title
   @Value("${disc.artilst}") String artilst){
     this.title=title;
     this.artilst=artilst;
   }

为了使用占位符,必须配置一个PropertyPlaceholderConfigurer bean或者PropertySourcePlaceholderConfigurer bean 推荐使用后者,因为可以根据Environment极其属性源解析占位符

2.3.2SpEL

形式: "#{...}" 细节这里不详细介绍,类似EL

3.条件化的bean

3.1作用

使一个或多个bean在某种特定条件下才会创建(但又不适用于@profile),spring4引入了一个新的@Conditional注解 ,他可以用到带有@Bean 注解的方法上。给定条件为true则创建这个bean,否则忽略该bean

3.2Condition接口

通过实现Condition接口的matches方法

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  // TODO Auto-generated method stub
  return context.getEnvironment().getProperty("os.name").contains("Linux");
}
 
通过`ConditionContext`,我们可以实现如下几点:
  • 借助getRegistry()返回的BeanDefinitionRegstry检查bean定义;
  • 借助getBeanFactory()返回的ConfigurableListBeanFactory检查Bean是否存在,探查bean的属性;
  • 借助getEnvironment()返回的Environment检查环境变量;
  • 借助getClassLoader()返回的ClassLoader加载并检查类是否存在。

    AnnotatedTypeMetadata可以检查是否还存在其他注解

    4.bean的作用域

    4.1作用域

    • 单例(Singleton):整个应用中,只创建一个bean的实例
    • 原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个实例
    • 会话(Session):在Web应用中,微每个回话创建一个实例
    • 请求(Request):在Web,应用中,每次请求都创建一个实例

4.2配置beand的作用域

  1. 使用@Scope注解
  2. 使用xml进行配置(作为bean的属性)

SpringAOP

本文仅在springAOP基础上进行说明,并不对AspectJ等其他框架进行详细介绍

Spring AOP相关概念

  • 通知(Advice):定义了切面的目标,他所要完成的任务,还定义了切面何时被使用
  • 连接点(Joint Point):程序执行过程中可插入切面的一个(时间)点
  • 切点(Point Cut):定义了切面的位置,每个通知都和一个切点表达式相关联
  • 切面(Aspect):切点和通知的结合,通知和切点定义了切面的全部内容
  • 引入(Introduction):在不修改现有类的情况下,向现有类添加方法和属性
  • 织入(Weaving):把切面应用到对象并创建新的代理对象的过程(springAOP)

Spring的AOP实现
纯java实现,无需特殊的编译过程,不需要控制类加载层次
目前只支持方法执行连接点(通知Spring Bean的方法执行)
不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IoC容器之间的整合,用于帮助解决企业应用中的常见问题
Spring AOP不会与AspectJ竞争,从而提供综合全面的AOP解决方案

SpringAOP使用

#### 通过切点选择连接点 Spring支持的AspectJ切点指示器

 

AspectJ解释器描述
arg() 限制连接点匹配参数为指定类型的执行方法
@arg() 限制连接点匹配参数由指定注解标注的执行方法
execution() 用于匹配连接点的执行方法
this() 限制连接点匹配AOP代理的bean引用为指定类型
target() 限制连接点匹配目标对象为指定的类
@target() 限制连接点匹配具有指定注解的类
within() 限制连接点匹配指定的类型
@within() 限制连接点匹配指定注解标注的类型
@annotation() 限制陪陪带有指定注解的连接点

Target() this()就是属于他动态植入的方式,within是静态植入的。故target(),this()需要在运行时才能确定那些被拦截。 比如刚才的例子,我们在给Animal加多一个实现类,用target() 他仍然可以被拦截。 所以target()和this()会用继承关系作用,也就是说:如果你的signature是一个基类,那么这个pointcut同时也会对他的子类也起作用。
另外target 和 this 可以获取他们对应的实例。 但是within没法作到。
target()是指:我们pointcut 所选取的Join point 的所有者,直白点说就是: 指明拦截的方法属于那个类。
this()是指: 我们pointcut 所选取的Join point 的调用的所有者,就是说:方法是在那个类中被调用的。

###创建可复用的切点

使用@Pointcut()注解

@Pointcut("execution(** spring.aop.aspect.joint(..))")
pubic void cut(){}
 
  @Before("cut()")
  public void beforeadvice(){
    System.out.println("Before");
  }

通过使用注解声明了一个切点,joint方法调用时执行通知

###使用AOP为Bean引入新功能

使用@DeclareParents()注解

用法
@DeclareParents(value="edu.ex.aoptest.aspect.service.AnnotationService",
        defaultImpl= DefaultDynamicService.class)
  public static DynamicService ds;
  • value属性指定了那种类型的bean要引入该接口(标记符后带加号表示是其子类型)
  • defaultImpl属性指定了提供实现的类
  • 注解标记的静态属性表示要引入的接口

id:404728459
引继码:781057871958

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...