转载

Spring 基础

什么是耦合和内聚

耦合性 (Coupling),也叫耦合度,是对模块间关联程度的度量。

内聚标志 一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽和局部化概念的自然扩展。

Spring核心概念介绍

IoC(核心中的核心):Inverse of Control,控制反转。 对象的创建权力由程序反转给Spring框架。

DI:Dependency Injection,依赖注入。 在Spring框架负责创建Bean对象时,动态的将依赖对象注入到

Bean组件中!!

AOP:Aspect Oriented Programming,面向切面编程。 在不修改目标对象的源代码情况下,增强IoC容器

中Bean的功能。

Spring容器:指的就是IoC容器,底层也就是一个BeanFactory。

核心基础

基于XML的使用

IOC配置

在Spring 的XML文件中通过一个 bean标签 ,完成IoC的配置。

bean标签

bean标签作用:

用于配置被spring容器管理的bean的信息。

默认情况下它调用的是类中的【无参构造函数】。如果没有无参构造则不能创建成功。

bean标签属性:

id:给对象在 容器中 提供一个唯一标识。用于获取对象。

class:指定类的全限定名。用于反射创建对象。默认情况下 调用无参构造函数 。

init-method :指定类中的初始化方法名称。

destroy-method :指定类中销毁方法名称。比如DataSource的配置中一般需要指定destroy-

method=“close”。

scope:指定对象的作用范围。

singleton : 默认值 ,单例的(在整个容器中只有一个对象),生命周期如下:

对象出生:当应用加载,创建容器时,对象就被创建了。

对象活着:只要容器在,对象一直活着。

对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

prototype :多例的.每次访问对象时,都会重新创建对象实例。生命周期如下:

对象出生:当使用对象时,创建新的对象实例。

对象活着:只要对象在使用中,就一直活着。

对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

request :将Spring 创建的 Bean 对象存入到 request 域中.

session :将Spring 创建的 Bean 对象存入到 session 域中.

global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么

globalSession 相当于 session.

bean实例化的三种方式

第一种:使用默认无参构造函数(重点)

在默认情况下:它会根据默认无参构造函数来创建类对象。

如果 bean 中没有默认无参构造函数,将会创建失败。

<bean id="userService" class="com.kkb.spring.service.UserServiceImpl"/>

第二种:静态工厂(了解)

使用 StaticFactory 类中的静态方法 createUserService 创建对象,并存入spring 容器:

/**
 * 模拟一个静态工厂,创建业务层实现类
 */
 public class StaticFactory {

public static UserService createUserService(){

return new UserServiceImpl();


}
}
<bean id="userService" class="com.kkb.spring.factory.StaticFactory" factory-
method="createUserService"></bean>
<!-- 此种方式是:
 使用 StaticFactory 类中的静态方法 createUserService 创建对象,并存入 spring 容器
 id 属性:指定 bean 的 id,用于从容器中获取
 class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法


-->

第三种:实例工厂(了解)

/**
 * 模拟一个实例工厂,创建业务层实现类
 * 此工厂创建对象,必须现有工厂实例对象,再调用方法
 */ 5 public class InstanceFactory {

public UserService createUserService(){

return new UserServiceImpl();


}
}
<bean id="instancFactory" class="com.kkb.factory.InstanceFactory"></bean>
<bean id="userService" factory-bean="instancFactory" factory-
method="createUserService"></bean>
<!-- 此种方式是:

 * 先把工厂的创建交给 spring 来管理。
 * 然后在使用工厂的 bean 来调用里面的方法

factory-bean 属性:用于指定实例工厂 bean 的 id。

factory-method 属性:用于指定实例工厂中创建对象的方法。


-->

DI配置

依赖指的就是Bean实例中的属性


依赖(属性)分为:简单类型(8种基本类型和String类型)的属性、POJO类型的属性、集合数组类型的属性。

什么是依赖注入

依赖注入:Dependency Injection。它是 spring 框架核心 IoC 的具体实现。

为什么要进行依赖注入

我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。

那如果一个bean中包含了一些属性,那么spring帮我们实例化了bean对象之后,也需要将对应的属性信息进行赋值

操作,这种属性赋值操作,就是所谓的依赖注入(获取值、注入属性)

依赖注入的方式

public class UserServiceImpl implements UserService {
 private int id;
 private String name;


public UserServiceImpl(int id, String name) {

this.id = id;

this.name = name;
 }
 @Override

public void saveUser() {

System.out.println("保存用户:id为"+id+",name为"+name+"


Service实现");
}
}
<bean id="userService" class="com.kkb.spring.service.UserServiceImpl">
 <constructor-arg name="id" value="1"></constructor-arg>
 <constructor-arg name="name" value="zhangsan"></constructor-arg>

</bean>
<!-- 使用构造函数的方式,给 service 中的属性传值要求:类中需要提供一个对应参数列表的构造函数。
涉及的标签:constructor-arg

 * index:指定参数在构造函数参数列表的索引位置
 * name:指定参数在构造函数中的名称
 * value:它能赋的值是基本数据类型和 String 类型
 * ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean

--!>

set方法注入(重点)

手动装配方式(XML方式)

1 - 需要配置bean标签的子标签property

2 - 需要配置的bean中指定setter方法。

自动装配方式(注解方式,后面讲解)

1

  • @Autowired:
  • 作用一:查找实例,从spring容器中根据Bean的类型(byType)获取实例。

2

3 - 作用二:赋值,将找到的实例,装配给另一个实例的属性值。

4 - 注意事项:一个java类型在同一个spring容器中,只能有一个实例

5

  • @Resource:

6 - 作用一:查找实例,从spring容器中根据Bean的名称(byName)获取实例。

7 - 作用二:赋值,将找到的实例,装配给另一个实例的属性值。

8

  • @Inject:

9

使用p名称空间注入数据

本质上还是调用set方法,自行了解

  1. 步骤一:需要先引入 p 名称空间

1

在schema的名称空间中加入该行:xmlns:p="http://www.springframework.org/schema/p"

  1. 步骤二:使用p名称空间的语法

1

p:属性名 = ""

2

3

p:属性名-ref = ""

  1. 步骤三:测试

开课吧Java高级架构师1

<bean id="person" class="com.kkb.spring.demo.Person" p:pname="老王" p:car2-

ref="car2"/>

2

<bean id="car2" class="com.kkb.spring.demo.Car2" />

依赖注入不同类型的属性

简单类型(value)

1

<bean id="userService" class="com.kkb.spring.service.UserServiceImpl">

2 <property name="id" value="1"></property>

3 <property name="name" value="zhangsan"></property>

4

</bean>

引用类型(ref)

ref就是reference的缩写,是引用的意思。

1

<bean id="userService" class="com.kkb.spring.service.UserServiceImpl">

2

<property name="userDao" ref="userDao"></constructor-arg>

3 </bean>

4 <bean id="userDao" class="com.kkb.spring.dao.UserDaoImpl"></bean>

集合类型(数组)

  1. 如果是数组或者List集合,注入配置文件的方式是一样的

1

2

<bean id="collectionBean" class="com.kkb.demo5.CollectionBean">

<property name="arrs">

3

<list>

<!-- 如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签 -->

4

5

<value>美美</value>

6

<value>小风</value>

7

<bean></bean>

8 </list>

9 </property>

10

</bean>

  1. 如果是Set集合,注入的配置文件方式如下:

1

2

<property name="sets">

<set>

3 <!-- 如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签 -->

4 <value>哈哈</value>

5

6

7

<value>呵呵</value>

</set>

</property>

开课吧Java高级架构师3. 如果是Map集合,注入的配置方式如下:

1

<property name="map">

2

<map>

3 <entry key="老王2" value="38"/>

4 <entry key="凤姐" value="38"/>

5

<entry key="如花" value="29"/>

6

</map>

7

</property>

  1. 如果是 Properties 集合的方式,注入的配置如下:

1

<property name="pro">

2

<props>

3 <prop key="uname">root</prop>

4 <prop key="pass">123</prop>

5

</props>

6

</property>

基于注解和XML混合方式的使用

1

  • 学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样的,都

是要降低程序间的耦合。只是配置的形式不一样。

2

  • 关于实际的开发中到底使用xml

还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌

握。

3

  • 我们在讲解注解配置时,采用上一章节的案例,把 spring 的 xml 配置内容改为使用注解逐步实现。

IoC注解使用方法

第一步:spring配置文件中,配置context:component-scan标签

第二步:类上面加上注解@Component,或者它的衍生注解@Controller、@Service、@Repository

开课吧Java高级架构师常用注解

IoC注解(创建对象)

相当于:

1

<bean id="" class="">

Component注解

作用:

1

把资源让 spring 来管理。相当于在 xml 中配置一个 bean。

属性:

1

value:

指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名,首字母小写。

2

Controller&Service&Repository注解

他们三个注解都是针对@Component的衍生注解,他们的作用及属性都是一模一样的。他们只不过是提供了更加明确

的语义化。

注意:如果注解中有且只有一个属性要赋值时,且名称是 value,value 在赋值时可以不写。

1 - @Controller:一般用于表现层的注解。

2 - @Service:一般用于业务层的注解。

3 - @Repository:一般用于持久层的注解。

DI注解(依赖注入)

相当于:

1 <property name="" ref="">

2 <property name="" value="">

@Autowired

@Autowired默认按 类型装配 (byType),

@Autowired是由AutowiredAnnotationBeanPostProcessor类实现

@Autowired是spring自带的注解

开课吧Java高级架构师@Autowired 默认情况下要求依赖对象必须存在 ,如果需要允许null值,可以设置它的required属性为

false,如:@Autowired(required=false)

如果我们想 按名称装配 (byName)可以结合 @Qualifier 注解进行使用

@Qualifier

在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。

它在给 字段注入 时不能独立使用, 必须和@Autowire

但是给方法参数注入时,可以独立使用。

一起使用 ;

@Resource

@Resource默认 按名称装配 (byName),可以通过@Resource的name属性指定名称,如果没有指定name属性,

当注解写在字段上时,默认取字段名进行按照名称查找,当找不到与名称匹配的bean时才按照类型进行装配。

@Resource属于J2EE JSR250规范的实现

但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

推荐使用@Resource注解,因为它是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

@Inject

@Inject是 根据类型进行自动装配 的,如果需要按名称进行装配,则需要配合 @Named ;

@Inject是JSR330中的规范,需要导入javax.inject.Inject;实现注入。

@Inject可以作用在变量、setter方法、构造函数上。

@Value

给 基本类型和String类型 注入值

可以使用占位符获取属性文件中的值。

1 @Value(“${name}”)//name是properties文件中的key

2 private String name;

@Autowired、@Resource、@Inject区别

  1. @Autowired是spring自带的,@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,需要导入不

同的包

  1. @Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性
  2. @Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
  3. @Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用

改变Bean作用范围的注解

@Scope:指定 bean 的作用范围,相当于下面的配置:

1

<bean id="" class="" scope="">

属性:

开课吧Java高级架构师1

value:指定范围的值。取值:singleton prototype request session globalsession

生命周期相关注解

@PostConstruct

@PreDestroy

相当于:

1

<bean id="" class="" init-method="" destroy-method="" />

关于注解和XML的选择问题

注解的优势:

配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。

XML 的优势:

修改时,不用改源码。不涉及重新编译和部署。

Spring 管理 Bean 方式的比较:

原文  https://segmentfault.com/a/1190000021097363
正文到此结束
Loading...