Spring入门学习

Spring 学习

Spring 基础介绍

学习轻量级的控制反转(IOC),面向切面(AOP)

什么是 Spring?

  • 通过 IOC 的技术达到松耦合的目的
  • AOP 的支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发。系统级的服务:与具体的业务代码无关,无论什么都需要应用的服务
  • 包含并管理应用对象的配置和生命周期,这个意义上是一种容器
  • 将简单的组件组合称为复杂的应用,这个意义上是框架

Why Spring?

我们将对象的生命周期的管理交给了 Spring,所有的对象都叫做 bean,管理对象的容器叫做 bean 容器,省去了对象的创建和开销的过程。

作用

  • 容器
  • 对多种技术的支持
  • AOP:事务管理,日志等
  • 提供了众多方便的辅助类(JDBC 等)

适用范围

  • 单独使用 Bean 容器,Bean 管理
  • 使用 AOP 进行切面处理
  • 其他的,如对消息的支持

Spring 框架

框架与类库

  • 框架封装了逻辑、高内聚的,类库则是松散的工具的组合
  • 框架专注于某一领域,类库更通用

Spring IOC 容器

接口及面向接口编程

接口:声明没有实现
抽象类:与一般的一样,除了不能实例化

什么是 IOC

控制反转,控制权的转移,我们并不负责依赖对象的创建和维护,而是需要使用的时候,由外部容器负责创建和维护。

DI(依赖注入),负责对象组装功能。在 IOC 容器在运行期间,动态的将某种依赖关系注入到对象当中。

目的 :创建对象并且组装对象之间的关系。

获得依赖对象的过程被反转了。

Spring 的 Bean 配置和初始化

Spring 对于 Bean 整个的使用有两种方式:一种是通过注解,一种是基于 xml 的配置。

xml 里面 id,class(地址)

初始化过程,基础,两个包

  • BeanFactory 提供配置结构和基本功能,加载并初始化 Bean
  • ApplicationContext 保存了 Bean 对象,也就是容器。加载方式:
    加载本地文件;绝对路径
    Classpath;相对路径
    web 应用中依赖 servlet 或者 Listener

Spring 注入

容器加载 bean 的时候,完成对变量的赋值行为。

常用的两种方式:设值注入,构造注入

设值注入

也就是通过 set 的方式注入。

1
2
3
4
5
6
<bean id="injection" class="top.wuxiya.spring.Hello">
//ref指向的是id,也就是一个bean的引用,赋值给命名叫$name的变量
<property name="injectionDAO" ref="injectionDAO"></property>
</bean>

<bean id="injectionDAO" class="top.wuxiya.spring.HelloDAO"></bean>

构造注入

也就是通过 构造方法的方式注入。

注意:当通过构造注入的时候,构造器传入的变量名称必须与 name 设定的一致。

构造中,看 name。name 名称与传入的变量名匹配。

set 注入中,看类型。

一般来说最好都一样就不用区分了。

1
2
3
4
5
6
7
    <bean id="injectionService" class="top.wuxiya.spring.Hello">
//ref指向的是id,也就是一个bean的引用,赋值给命名叫$name的变量
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean>

<bean id="injectionDAO" class="top.wuxiya.spring.HelloDAO"></bean>
`

DAO——数据库
service——业务逻辑的部分

Bean 的配置

Bean 的配置项

获取 Bean 的两种方式:通过 Id 来获取,通过 Bean 的类型来获取

  • Id:唯一标识
  • Class:实例化的具体类——必须
  • Scope:作用域
  • 构造器参数
  • Properties:属性
  • 懒加载模式
  • 自动装配的模式
  • 初始化和销毁的方法

Bean 的作用域

:两种模式,singleton(默认),prototype

  • singleton:单例模式,一个 Bean 容器中只存在一个。默认
  • prototype:每次请求都创建新的实例,destroy 方式不生效
  • request:每次 http 请求创建一个实例且仅在但钱 request 内有效
  • session:同上,当前 session 中有效
  • glodbal session:单点登陆??

Bean 的生命周期

初始化两种

  • 一种为在 Bean 声明中添加 init-method=”methodName”
  • 实现 InitializingBean 接口,覆盖 afterPropertiesSet(),自动调用这个方法

销毁两种

  • 一种为在 Bean 声明中添加 destory-method=”methodName,cleanup”
  • 实现 DisposableBean 接口,覆盖 destroy(),自动调用这个方法

全局初始化和销毁方法
在 beans 中添加,default-init-method=”name”,default-destory-method=”name”

默认的方法可以不被实现,并且只要局部有一种实现就被覆盖。

局部初始化的两种方式,必须实现,其中接口的优先级大于方法的添加。

Aware 接口

  • 实现了 Aware 接口的 bean 在初始化之后,可以获取对应资源
  • 对 Spring 进行简单的扩展提供了方便的入口
  • 可以对 Spring 对应资源进行操作(慎重)

比如得到加载当前 bean 的上下文

Bean 的自动装配(Autowiring)

  • No 不做任何操作,默认
  • byname:根据属性名。设置,并且需要设置 set 方法。这个和 set 注入类似(看传入名),只不过不用再每一个 bean 里面显示声明 property。
  • byType:bean 的类型。多个类型抛异常。和 bean 的 ID 没有关系,在 set 方法(看类型)中匹配类型。
  • constructor:应用于构造器参数。在构造方法中查找构造器方法传入的类型。没有找到抛异常

Resources

针对资源文件的统一接口

Bean 的注解

Bean 管理的类注解实现

类的注解

  • @Component 是一个通用注解,可用于任何 bean
  • @Repository:用于注解 DAO 类,即持久层
  • @Service:Service 类,服务层
  • @Controller 用于 Controller 类,即控制层(MVC)

元注解:许多注解可以作为自己的代码,即“元数据注解”。可以用于领域给注解。还可以定制注解

类的自动检测及 Bean 的注册

  • 默认情况下,类被自动发现并注册 bean 的条件是:使用@Component,@Repository,@Service,@Controller 注解或者使用@Component 的自定义注解
  • 使用过滤器进行自定义扫描,修改自动发现的行文
  • 还可以禁用自动发现与注册

定义 bean

  • 可以显示指定 Bean 的 name。否则默认是类名的小写。
  • 还可以自定义命名的规则(一定要包含一个无参的构造器)。

作用域@Scope

  • @Scope(“prototype”)
    @Repository
  • 也可以自定义设置 scope

代理方式

使用 scoped-proxy 属性指定代理,有三个值可选:no,interfaces,targetClass

Bean 的(Autowiring)注解说明

@Required(不常用)

  • 是用于 bean 属性的 setter 方法
  • 表示受影响的 bean 属性必须在配置时被填充,通过在 bean 定义或通过自动装配一个明确的属性值

@Autowired

使用 1

  • 传统的 setter 方法
  • 也可以用于构造器或者成员变量
  • 我们可以注解那些众所周知的解析依赖性接口,比如:BeanFactory,MessageSource 等

注意

  • 默认情况下,如果找不到和实施的 bean 会抛出异常,所有可以用@Autowired(required=false)来避免
  • 每一个类只能有一个构造器被标注为 true
  • 如果为 true 的必要属性,那么建议用@Resource

使用 2

  • 可以通过添加注解给需要该类型实例的数组的字段和方法,以提供 ApplicationContext 中所有特定类型的 bean
    public void setFunc(Set name){
    this.name=name;
    }
    List;
    Map<String,BeanType>(String 为 bean 的 id)
  • 如果希望数组有序,可以让 bean 实现@Order 注解(Order 只针对 List 或 set)

注意
@Autowired 是由两种类型的 Bean 进行处理的,因此自定义这两种类的时候,我们需要通过

@Qualifier

可以指定特定的唯一的 bean,当子类有多个类型的时候。

我们一般用@Resource 来通过注解,这是一个与所声明类型无关的匹配过程。

  • @Auto 用于属性,构造器,多参数方法,允许在参数级别使用@Qual 缩小范围
  • @Resource 适用于成员变量、只有一个参数的 setter 方法,使用构造器,多参数用@Qual
1
2
3
@Autowired()
@Qualifier("beanImplTwo")
private BeanInterface beanInterface;

基于 Java 的容器注解

@Configuration

  • @Configuration(类注解,相当于一个配置类)
    @Bean(方法注解)
    public Myservice myService(){
    return new MyserviceImpl();
    //相当于定义了一个 id 叫做 myService 的 Bean
    }

@Bean(默认单例)

  • 自定义 Bean 的那么@Bean(name=”myName”)。默认的是方法的名称
    @Bean(init-method=””)
    @Bean(destroyMethod=””)

@ImportResource,加载资源文件

配置数据库
在 xml 中,用<context:property-placeholder location=”…./jdbc.properties”>

下面用${jdbc.url}(username,password)

仍然

@Configuration
@ImportResource(“classpath:…”)

@Value(“${jdbc.url}”)
@Value(“${jdbc.username}”)

  • 需要注意的是,username 拿到的是登录系统的用户名,因此一般来说数据库的用户名都加 jdbc

也就说与操作系统重复的都需要进行性注意

@Scope

  • @Bean
    @Scope(value=”session”,proxyMode=)

基于泛型的自动装配

@Resource

  • 注解变量或者 setter
  • @–(name=””),默认是属性名和 setter 方法得出