【java总结】框架之Spring

【java总结】框架之Spring

Spring基础

什么是Spring?

  • Spring是一个开源的免费的框架(容器)
  • Spring是一个轻量级的,非入侵式的框架
  • 两个特性:控制反转(IOC)面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持

使用Spring的好处

方便解耦——Spring提供的IoC容器实现了对象依赖关系的管理,避免了硬编码导致的耦合。

支持AOP——Spring提供的AOP功能,方便进行面向切面编程。

声明式事物——Spring提供了通过声明的方式灵活的进行事务管理。

方便程序测试——可以用非容器以来的编程方式进行几乎所有的测试工作。

集成了多种优秀框架——Spring提供了对各种优秀框架(如Struts、Hibernate、Hessian、Quartz等)的直接支持。

降低Java EE API的使用难度——Spring对很多难用的Java EE API(如JDBC、JavaMail、远程调用等)提供了一个薄薄的封装层,使得这些Java EE API的使用难度大为降低。

Java源码是经典学习范例——Spring的源码设计精妙、结构清晰,是Java技术的最佳实践的范例。

事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务 (JTA)。

异常处理:Spring提供方便的API把具体技术相关的异常(比如由JDBC,HibernateorJDO抛 出的)转化为一致的unchecked异常。

Spring组成

image
  • 核心容器 :核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。 BeanFactory 使用 控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。Spring框架建立在此模块之上,它使Spring成为一个容器。

  • Spring 上下文 :Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

  • Spring AOP :通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

  • Spring DAO

    DAO(Data Access Object)是用于访问数据的对象,虽然在大多数情况下将数存在数据库中,但这并不是唯一的选择,也可以将数据存储到文件中或LDAP中。DAO不但屏蔽了数据存储的最终介质的不同,也屏蔽了具体的实现技术的不同。

    JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

  • Spring ORM :Spring 框架插入了若干个 ORM 框架,支持我们在直接JDBC之上使用一个对象/关系映射映射(ORM)工具,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

  • Spring Web 模块 :Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

  • Spring MVC 框架 :MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

BeanFactory和ApplicationContext有什么区别?

BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便 在接收到客户端请求时将对应的bean实例化。

最常用的BeanFactory实现是XmlBeanFactory类。

最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory,它根据XML文件中的 定义加载beans。该容器从XML文件读取配置元数据并用它去创建一个完全配置的系统或应 用。

BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端 的配置中解放出来。BeanFactory还包含 了bean生命周期的控制,调用客户端的初始化方法 (initialization methods)和销毁方法(destruction methods)。

从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设 置,根据请求分发bean的功能。但applicationcontext在此基础上还提供了其他的功能。

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文件读取上下文。

4.AnnotationConigApplicationContext(基于Java配置启动容器)

核心功能

IOC

控制反转IoC

IoC的字面意思是控制反转,它包括两部分的内容:

  • 控制:在上述案例中,控制就是选择套餐中汉堡和饮品的控制权。
  • 反转:反转就是把该控制权从套餐本身中移除,放到专门的服务员手中。

对于Spring来说,我们通过Spring容器管理来管理和控制Bean的装配。

依赖注入

由于IoC这个重要的概念比较晦涩隐讳,Martin Fowler提出了DI(Dependency Injection,依赖注入)的概念用以代替IoC,即让调用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。

Spring的核心模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描述,由IoC容器负责类的创建,管理,获取等工作。让开发者可以从这些底层实现类的实例化、依赖关系装配等工作中解脱出来,专注于更有意义的业务逻辑开发。

BeanFactory接口是Spring框架的核心接口,实现了容器很多核心的功能。

Context模块构建于核心模块之上,扩展了BeanFactory的功能,包括国际化、Bean生命周期控制、框架事件体系、资源加载透明化等功能;还提供了众多企业级服务的支持,如邮件服务、任务调度、JNDI、EJB、远程访问等。ApplicationContext是Context模块的核心接口。

表达式语言(Expression Language)是统一表达式语言的一个扩展,用于查询和管理运行期的对象,支持设置和获取对象属性,调用对象方法,操作数组、集合等。使用它可以很方便的通过表达式和Spring IoC容器进行交互。

什么是SpringIOC容器?

SpringIOC负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管 理这些对象的整个生命周期。

AOP

AOP(Aspect Oriented Programing)即面向切面编程,适用于那些具有横切逻辑的应用场合,是OOP的重要补充。通过 spring 的 AOP 技术,就可以在不修改 代码的情况下完成需求。

AOP有几个重要的概念:

  1. 连接点(Joinpoint):一段代码中一些具有边界性质的点,如类开始初始化前、类初始化后、方法调用前后、方法抛出异常。Spring仅支持方法的连接点。
  2. 切点(Pointcut):AOP通过切点定位连接点,相当于是连接点的定位条件。在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述。
  3. 增强(Advice):增强是指在目标连接点上织入一段程序代码。
  4. 目标类(Target):织入增强逻辑的目标类。
  5. 引介(Introduction): 引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
  6. 织入(Weaving):是将增强添加对目标类具体连接点上的过程。根据不同的实现技术,AOP有三种织入的方式(Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入):
    a. 编译期织入,这要求使用特殊的Java编译器。
    b. 类装载期织入,这要求使用特殊的类装载器。
    c. 动态代理织入,在运行期为目标类添加增强生成子类的方式。
  7. 代理(Proxy):一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。
  8. 切面(Aspect):切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义。Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
Spring AOP 实现原理

Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。JDK 动态代 理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。

概念

Spring配置文件

Spring配置文件是个XML文件,这个文件包含了类信息,描述了如何配置它们,以及如何相 互调用。

什么是SpringIOC容器?

SpringIOC负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管 理这些对象的整个生命周期。

什么是Spring inner beans?

其他介绍

为什么说Spring是一个容器?

用来形容它用来存储单例的bean对象这个特性。

Spring Bean的生命周期?

① Spring IoC容器找到关于Bean的定义并实例化该Bean。
② Spring IoC容器对Bean进行依赖注入。
③ 如果Bean实现了BeanNameAware接口,则将该Bean的id传给setBeanName方法。
④ 如果Bean实现了BeanFactoryAware接口,则将BeanFactory对象传给setBeanFactory方法。
⑤ 如果Bean实现了BeanPostProcessor接口,则调用其postProcessBeforeInitialization方法。
⑥ 如果Bean实现了InitializingBean接口,则调用其afterPropertySet方法。
⑦ 如果有和Bean关联的BeanPostProcessors对象,则这些对象的postProcessAfterInitialization方法被调用。
⑧ 当销毁Bean实例时,如果Bean实现了DisposableBean接口,则调用其destroy方法。

image-20200806223614200

哪些是重要的bean生命周期方法?你能重载它们吗?

有两个重要的bean生命周期方法,第一个是setup,它是在容器加载bean的时候被调用。第 二个方法是teardown它是在容器卸载类的时候被调用。 Thebean标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制 初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。

可以在Spring中注入一个null和一个空字符串吗?

可以

Spring使用

构建流程

首先编写pojo类,工厂

//定义一个宠物接口类
public interface Pet {
	public void testPet();
}
//定义两个宠物实现类

public class Dog implements Pet {
	private String name;
	public void setName(String name){
		this.name = name;
	}
	@Override
	public void testPet() {
		System.out.println(name+":狗喜欢吃骨头!");
	}
}


public class Cat implements Pet {
	private String name;
	public void setName(String name){
		this.name = name;
	}
	@Override
	public void testPet() {
		System.out.println(name+":猫喜欢吃鱼!");
	}
}
//定义一个静态工厂类

public class PetFactory {
	public static Pet getPet(String arg){
		if("dog".equals(arg)){
			return new Dog();
		}else{
			return new Cat();
		}
	}
}

一、创建applicationContext.xml文件

在这个文件中托管bean

<bean id = "dog" class = "cn.jimu98.factory.PetFactory" factory-method="getPet">
    <constructor-arg value="dog" />
    <property name="name" value = "旺财" />
</bean>
<bean id = "cat" class = "cn.jimu98.factory.PetFactory" factory-method="getPet">
    <constructor-arg value="cat" />
    <property name="name" value = "咪咪" />
</bean>

class属性就是指定的静态工厂类,factory-method指定工厂的静态方法。如果factory-method需要参数,则需要使用constructor-arg元素传入。

二、初始化容器

ApplicationContext ac = new ClassPathXmlApplicationContext(“ApplicationContext.xml”); //获取Spring 的上下文对象 也可以说拿到了容器

三、获取对象 getBean(“”)

//测试方法
public static void main(String[] args) throws Exception {
		ApplicationContext ac = new ClassPathXmlApplicationContext("appicationContext.xml");
		Pet p1 = ac.getBean("dog", Pet.class);
		p1.testPet();
		Pet p2 = ac.getBean("cat", Pet.class);
		p2.testPet();
	}
}
构造方法
无参构造

是指在实体类种通过无参构造器构造的bean

有参构造

ac.getBean(“dog”, Pet.class);

通过注解方式实现

在类上添加@Service注解

@Component:在Bean的实现类上直接标注,可以被Spring容器识别
@Repository:用于对DAO实现类进行标柱
@Service:用于对Service实现类进行标注
@Controller:用于对Controller实现类进行标注

—————————–分割线

其他

其实xml配置文件分类可多 细细道来

调用实例工厂方法创建Bean
<bean id = "petFactory" class = "cn.jimu98.factory.PetOneFactory" />
<bean id = "dog" factory-bean="petFactory" factory-method="getPet">
    <constructor-arg value="dog" />
    <property name="name" value = "旺财" />
</bean>

调用静态工厂方法只需要工厂类即可,而调用实例工厂方法则需要工厂实例。所以配置实例工厂方法与配置静态工厂方法基本相似,只有一点区别:配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂实例。

抽象Bean与子Bean

在实际开发中,有可能会出现这样的情况:随着项目越来越大,Spring配置文件出现了多个bean,配置具有大致相同的配置信息,只有少量信息不同,为了解决上面问题,可以考虑把多个bean配置中相同的信息提取出来,集中成配置模板——这个配置模板并不是真正的Bean。因此Spring不应该创建该配置模板,于是需要为该bean配置增加abstract属性值为true表示这是个抽象Bean。

<bean id=”steelAxe” class=”cn.jimu98.impl.SteelAxe” />
<bean id=”personTemplete” abstract=”true”>
	<property name=”name” value=”zhangsan” />
	<property name=”axe” ref=”steelAxe” />
</bean>
<bean id=”chinese” class=”cn.jimu98.impl.Chinese” parent=”personTemplete”/>
<bean id=”american” class=”cn.jimu98.impl.American” parent=”personTemplete”/>

Java中Bean的继承与Java中的继承有如下区别:

Spring中的子Bean和父Bean可以是不同类型,但Java中的继承则可保证子类是一种特殊的父类。
Spring中Bean的继承是实例之间的关系,因此主要表现为参数值的延续;而Java中的继承是类之间的关系,主要表现为方法、属性的延续。
Spring中的子Bean不可作为父Bean使用,不具备多态性;Java中的子类实例完全可以当成父类实例使用。

Bean类的配置项

① class

该配置项是强制项,用于指定创建Bean实例的Bean类的路径。

② name

该配置项是强制项,用于指定Bean唯一的标识符,在基于 XML 的配置项中,可以使用 id和或 name 属性来指定 Bean唯一 标识符。

③ scope

该配置项是可选项,用于设定创建Bean对象的作用域。

④ constructor-arg

该配置项是可选项,用于指定通过构造函数注入依赖数据到Bean。

⑤ properties

该配置项是可选项,用于指定通过set方法注入依赖数据到Bean。

⑥ autowiring mode

该配置项是可选项,用于指定通过自动依赖方法注入依赖数据到Bean。

⑦ lazy-initialization mode

该配置项是可选项,用于指定IOC容器延迟创建Bean,在用户请求时创建Bean,而不要在启动时就创建Bean。

⑧ initialization

该配置项是可选项,用于指定IOC容器完成Bean必要的创建后,调用Bean类提供的回调方法对Bean实例进一步处理。

⑨ destruction

该配置项是可选项,用于指定IOC容器在销毁Bean时,调用Bean类提供的回调方法。

自动装配autowire

元素提供了一个default-autowire属性可以全局自动匹配,默认为no。 元素提供了一个指定自动装配类型的autowire属性,可以覆盖 元素的default-autowire属性,该属性有如下选项:

自动装配类型说明
no显式指定不使用自动装配。
byName如果存在一个和当前属性名字一致的 Bean,则使用该 Bean 进行注入。如果名称匹配但是类型不匹配,则抛出异常。如果没有匹配的类型,则什么也不做。
byType如果存在一个和当前属性类型一致的 Bean ( 相同类型或者子类型 ),则使用该 Bean 进行注入。byType 能够识别工厂方法,即能够识别 factory-method 的返回类型。如果存在多个类型一致的 Bean,则抛出异常。如果没有匹配的类型,则什么也不做。
constructor与 byType 类似,只不过它是针对构造函数注入而言的。如果当前没有与构造函数的参数类型匹配的 Bean,则抛出异常。使用该种装配模式时,优先匹配参数最多的构造函数。
default根据 Bean 的自省机制决定采用 byType 还是 constructor 进行自动装配。如果 Bean 提供了默认的构造函数,则采用 byType;否则采用 constructor 进行自动装配。
Bean的作用域
类型说明
singleton在Spring IoC容器中仅存在一个Bean实例,Bean以单实例的方式存在
prototype每次从容器中调用Bean时,都返回一个新的实例
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session同一个HTTP session共享一个Bean,不同的HTTP session使用不同的Bean,该作用域仅适用于WebApplicationContext环境
globalSession同一个全局Session共享一个Bean,一般用于Portlet环境,该作用域仅适用于WebApplicationContext环境
扫描注解定义对Bean

Spring提供了一个context命名空间,用于扫描以注解定义Bean的类。

<!--生命context命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="cn.jimu98.spring"/>
</beans>
base-package属性
  • 指定一个需要扫描的基类包,Spring容器会扫描这个包下的所有类,并提取标注了相关注解的Bean。
resource-pattern属性
  • 如果不希望扫描base-package下的所有类,可以使用该属性提供过滤
  • 该属性默认是**/*.class,即基包下的所有类
context:exclude-filtercontext:include-filter
类别示例说明
annotationcom.ankeetc.XxxAnnotation所有标注了XxxAnnotation的类。该类型采用目标类是否标志了某个注解进行过滤。
assignablecom.ankeetc.XxService所有继承或扩展XXXService的类。该类型采用目标类是否继承或者扩展了某个特定类进行过滤
aspectjcom.ankeetc..*Service+所有类名以Service结束的类及继承或者扩展他们的类。该类型采用AspectJ表达式进行过滤
regexcom.ankeetc.auto..*所有com.ankeetc.auto类包下的类。该类型采用正则表达式根据目标类的类名进行过滤
customcom.ankeetc.XxxTypeFilter采用XxxTypeFilter代码方式实现过滤规则,该类必须实现org.springframework.core.type.TypeFilter接口
use-default-filters属性
  • use-default-filters属性默认值为true,表示会对标注@Component、@Controller、@Service、@Reposity的Bean进行扫描。
  • 如果想仅扫描一部分的注解,需要将该属性设置为false。
<!-- 仅扫描标注了@Controller注解的类-->
<context:component-scan base-package="com.ankeetc.spring" use-default-filters="false">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
自动装配
方式一:通过xml文件实现自动装配
<bean id="people" class="cn.jimu98.pojo.Peopel" autowire="byName">
        <property name="name" value="张三"/>
</bean>

使用autowire关键字声明bean的自动装配方式。其可选值为byName、byType、constructor,default,no;这里讲前边两个。

1.byName

设置autowire属性为byName,那么Spring会根据class属性找到实体类,然后查询实体类中所有setter方法的名字,根据setter方法后面的名字(例如SetDog,则setter方法后面的名字为dog)再到配置文件中寻找一个与该名字相同id的Bean,注入进来。如图:

image-20200806213043989
2.byType

设置autowire属性为byType,那么Spring会自动寻找一个与该属性类型相同的Bean,注入进来。

image-20200806213100822

注意:使用byType这种方式,必须保证配置文件中所有bean的class属性的值是唯一的,否则就会报错

例如:下边这种方式是错误的,因为两个bean中的class属性的值重复了,会报错

image-20200806213136630
方式二:通过注解实现自动装配

注解是通过反射来实现的。

1.使用注解前的准备:

要使用注解,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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

注意:
<context:annotation-config/> 必须要写在xml中,这是用来开启注解的支持,如果不加上注解就无效。

2.1 Autowired注解【常用】
首先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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="cat" class="com.kuang.pojo.Cat"/>
    <bean id="dog" class="com.kuang.pojo.Dog"/>
    <bean id="people" class="com.kuang.pojo.Peopel">
        <property name="name" value="张三"/>
    </bean>
</beans>

然后在实体类的对应属性上添加@Autowired注解(也可以把注解放到对应属性的setter上),people类中依赖Dog类和Cat类。所以在people类中的dog和cat属性上要加上@Autowired,实现自动装配。

例如:

public class Peopel {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;

    public Cat getCat() {
        return cat;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Peopel{" +
                "cat=" + cat +
                ", dog=" + dog +
                ", name='" + name + '\'' +
                '}';
    }
}

重点:

(1)注解方法装配属性的过程:spring会默认优先根据(被注解修饰的)属性类型去容器中找对应的组件(bean),找到就赋值;若找到多个相同类型的组件,再将属性的名称作为组件(bean)的id去容器中查找。

(2)@Qualifier注解可以和使用Autowired搭配使用:@Qualifier指定需要装配的组件的id,而不是使用属性名。例如下边例子,spring就会优先在容器中查找id为“abcd”的组件。

public class Peopel {
    @Autowired
    @Qualifier(value = "cat")
    private Cat cat;
}

什么情况会使用到@Qualifier注解:当ioc容器根据属性类型去容器中找找到多个相同类型的组件,再将属性的名称作为组件(bean)的id去容器中查找找不到时就是用这两个注解搭配,指定需要装配的bean的id。

(3)在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用@Autowired(required= false)。这等于告诉 Spring:在找不到匹配 Bean 时也不报错。

2.2. Resource注解【不常用】

@Resource:可以和@Autowired一样实现自动装配功能,但是跟@Autowired不一样的是,它默认是按照组件名称进行装配的,按照组件名称找不到在根据属性类型去查找,再找不到就报错;他们另一个不同的地方就是@Autowired是Spring定义的; @Resource是java规范。

什么是Spring inner beans?

在Spring框架中,无论何时bean被使用时,当仅被调用了一个属性。一个明智的做法是将这 个bean声明为内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现。 比如,在我们的应用程序中,一个Customer类引用了一个Person类,我们的要做的是创建 一个Person的实例,然后在Customer内部使用。

public class Customer{
 private Person person;
 //Setters and Getters
}

public class Person{
 private String name;
 private String address;
 private int age;
 //Setters and Getters
}
<bean id="CustomerBean" class="com.somnus.common.Customer">
 <property name="person">
 <!-- This is inner bean -->
 <bean class="com.howtodoinjava.common.Person">
 <property name="name" value="lokesh" />
 <property name="address" value="India" />
 <property name="age" value="34" />
 </bean>
 </property>
</bean>

pring框架中的单例bean不是线程安全的。

请举例说明@Qualiier注解?

@Qualiier注解意味着可以在被标注bean的字段上可以自动装配。Qualiier注解可以用来取 消Spring不能取消的bean应用。 下面的示例将会在Customer的person属性中自动装配 person的值。

<bean id="customer" class="cn.jimu98.common.Customer" />
<bean id="personA" class="cn.jimu98.common.Person" >
 <property name="name" value="lokesh" />
</bean>

<bean id="personB" class="cn.jimu98.common.Person" >
 <property name="name" value="alex" />
</bean>
public class Customer{
 @Autowired
 private Person person;
}

//这样就会报错,因为不知道该使用哪个bean

public class Customer{
 @Autowired
 @Qualifier("personA")
 private Person person;
}

//使用@Qualiier注解就ok了

IOC

从注入方法上看,IoC可以分为:构造函数注入、属性注入、接口注入

构造函数注入
class KFCCombo {
    private Burger burger;
    private Drink drink;

    // 在此注入对应的内容
    public KFCCombo(Burger burger, Drink drink) {
        this.burger = burger;
        this.drink = drink;
    }
}
属性注入
class KFCCombo {
    private Burger burger;
    private Drink drink;

    // 在此注入对应的内容
    public void setBurger(Burger burger) {
        this.burger = burger;
    }

    // 在此注入对应的内容
    public void setDrink(Drink drink) {
        this.drink = drink;
    }
}
接口注入
interface InjectFood {
    void injectBurger(Burger burger);
    void injectDrink(Drink drink);
}

class KFCCombo implements InjectFood {
    private Burger burger;
    private Drink drink;
    
    // 在此注入对应的内容
    public void injectBurger(Burger burger) {
        this.burger = burger; 
    }
    // 在此注入对应的内容
    public void injectDrink(Drink drink) {
        this.drink = drink;
    }
}

接口注入和属性注入并无本质的区别,而且还增加了一个额外的接口导致代码增加,因此不推荐该方式。

资源访问
classpath:与classpath*:

假设有多个Jar包或者文件系统类路径下拥有一个相同包名(如com.ankeetc):

  • classpath:只会在第一个加载的com.ankeetc包的类路径下查找
  • classpath*:会扫描到所有的这些JAR包及类路径下出现的com.ankeetc类路径。

这对于分模块打包的应用非常有用,假设一个应用分为2个模块,每一个模块对应一个配置文件,分别为module1.yaml 、module2.yaml,都放在了com.ankeetc的目录下,每个模块单独打成JAR包。可以使用 classpath*:cn/jimu98/module*.xml加载所有模块的配置文件。

Spring配置

Spring有几种配置方式?

将Spring配置到应用开发中有以下三种方式:

1.基于XML的配置

2.基于注解的配置

3.基于Java的配置

如何用基于XML配置的方式配置Spring?
如何用基于Java配置的方式配置Spring?

定义一个配置类

怎样用注解的方式配置Spring?
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringIdolConfig {
	// Bean declaration methods go here
}

声明一个简单的Bean

@Bean
public Performer duke() {
	return new Juggler();
}

使用Spring的基于java的配置进行注入。

@Bean
public Performer duke15() {
	return new Juggler(15);
}
@Bean
public Performer kenny() {
    Instrumentalist kenny = new Instrumentalist();
    kenny.setSong("Jingle Bells");
    return kenny;
}

Spring面试题

Spring支持的事务管理类型

Spring支持两种类型的事务管理:

编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维 护。

声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置 来管理事务。

Spring 框架中用到了哪些设计模式?

代理模式—在 AOP 和 remoting 中被用的比较多。
单例模式:在 spring 配置文件中定义的 bean 默认为单例模式。
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
前端控制器:Spring 提供了 DispatcherServlet 来对请求进行分发。
视图帮助(View Helper ):Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码 整合在视图里。
依赖注入:贯穿于 BeanFactory / ApplicationContext 接口的核心理念。
工厂模式:BeanFactory 用来创建对象的实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值