Spring知识总结

1.Spring核心

  • IoC(Inverse of Control 控制反转): 将对象创建权利交给Spring工厂进行管理。 比如说 Book book = new Book();
    现在: Book book = Spring工厂.getBook();
  • AOP(Aspect Oriented Programming 面向切面编程),基于动态代理的功能增强方式。

2.IoC(Inverse of Control 控制反转)

Spring通过IoC的思想解决代码耦合问题。
简单的说就是引入工厂(第三者),将原来在程序中手动创建管理的依赖的UserDaoImpl对象,交给工厂来创建管理。


2.1 实现原理

在核心文件中配置bean标签,id属性为bean的名称,class属性指向要创建的对象类型的类字符串,Spring容器在启动后,就会通过bean的类字符串反射生成实例对象,存放到Spring容器中(工厂)

IoC底层实现:工厂(设计模式)+反射(机制) + 配置文件(xml)。


2.2 IoC容器装配Bean(基于注解)

2.2.1 Bean的定义(注册) – 扫描机制

  • xml做法 : ,用的方式创建对象

  • 注解做法 : spring2.5引入 @Component注解 如果放置到类的上面,相当于在spring容器中定义

当然仅仅在类上添加注解是不够的,我们还要让Spring容器能扫描到类,即开启注解扫描 <context:component-scan base-package="cn.itcast.spring"/>

实际开发中,使用的是@Component三个衍生注解(“子注解”)

  • @Service用于标注业务层组件、(如Service层)
  • @Controller用于标注控制层组件(如struts中的action层)
  • @Repository用于标注数据访问组件,(如DAO层组件

3.Bean获取的两种方式

通过IoC我们可以将对象交给Spring工厂管理了

Spring工厂我们可以理解成如下,在一开始的时候会根据核心配置中bean的类字符串生成实例对象,然后以id:实例或者类型:实例存到工厂中,我们此时可以通过两种方式来获取实例

public classFactory {
	public Object getBean(){
		Object bean = null;
		try {
			//传入类字符串,生产对象实例
			bean = Class.forName("cn.itcast.spring.a_quickstart.UserDAOImpl").newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		//返回具体类型的对象类型实例
		return bean;
	}
}

两种获取bean的方式

  • 1.通过spring容器中bean的id/name获取 (常用)
  • 2.根据bean的类型或者bean接口的类型获取,一般使用接口类型(如果根据类型获取,配置了多个类型的话,则抛出异常)
@Test
public void getBean(){
	 
	ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	//获取bean的两种方式
	//1.通过spring容器中bean的id/name获取
	//IUserService userService = (IUserService) ac.getBean("userService");
	
	//2.根据bean的类型或者bean接口的类型获取,一般使用接口类型
	IUserService userService = (IUserService) ac.getBean(IUserService.class);
	
	userService.login();
}

4.实例化bean的4种方法

  • 1.无参数构造器 (最常用)
    <bean id =“bean1” class=“cn.itcast.spring.b_xmlnewbean.Bean1” />
  • 2.静态工厂方法
    <bean id = “bean2” class=“cn.itcast.spring.b_xmlnewbean.Bean2Factory” factory-method=“getBean2” />
  • 3.实例工厂方法
    <bean id=“bean3Factory” class=“cn.itcast.spring.b_xmlnewbean.Bean3Factory”/>
    <bean id=“bean3” factory-bean=“bean3Factory” factory-method=“getBean3”/>
  • 4.FactoryBean方式。(源码底层用的多)
    <!-- spring在实例化Bean4Factory的时候会判断是否实现了FactoryBean接口,如果实现了就调用getObject方法返回实例 -->
    <bean id=“bean4” class=“cn.itcast.spring.b_xmlnewbean.Bean4Factory” />

5.DI注入

5.1 DI的实现

依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件(简单的说,可以将另外一个bean对象动态的注入到另外一个bean中。

DI的做法是:由Spring容器创建了Service、Dao对象,并且在配置中将Dao传入Servcie,那么Service对象就包含了Dao对象的引用。

那么如果并且在配置中将Dao传入Servcie?
我们只要在Service中定义属性提供setter方法,同事在配置中,通过property属性将引用指向Dao即可

public class UserServiceImpl implements IUserService{
	
	// 定义属性
	private IUserDAO userDAO;

	public void setUserDAO(IUserDAO userDAO) {
		this.userDAO = userDAO;
	}
	
}
<bean id="userDAO" class="cn.itcast.spring.a_quickstart.UserDAOImpl" />

<bean id ="userService" class="cn.itcast.spring.a_quickstart.UserServiceImpl">
	<property name="userDAO" ref="userDAO" />
</bean>
5.2 Bean属性的依赖注入(通过注解)

5.2.1 简单数据类型依赖注入
提供 @Value注解,可以完成简单数据的注入(不常用)

5.2.2 复杂类型数据依赖注入
(1) 使用@Value 结合SpEL
在属性声明上面注入,底层自动还是生成setCustomerDao()

@Value("#{customerDao}")
private CustomerDao customerDao;

(2) 使用@Autowired 结合 @Qualifier
单独使用@Autowired ,表示按照类型注入,会到spring容器中查找CustomerDao的类型,对应,class的属性值,如果找到,可以匹配。
使用@Autowired + @ Qualifier 表示按照名称注入,回到spring容器中查找customerDao的名称,对应,id的属性值,如果找到,可以匹配。

@Autowired//默认按照类型注入
private CustomerDao customerDao;

@Autowired//默认按照类型注入的
@Qualifier("customerDao")//必须配合@Autowired注解使用,根据名字注入
private CustomerDao customerDao;

(3) JSR-250标准(基于jdk) 提供注解@Resource
单独使用@Resource注解,表示先按照名称注入,会到spring容器中查找customerDao的名称,对应,id的属性值,如果找到,可以匹配。
如果没有找到,则会按照类型注入,会到spring容器中查找CustomerDao的类型,对应,class的属性值,如果找到,可以匹配,如果没有找到会抛出异常。

@Resource//默认先按照名称进行匹配,再按照类型进行匹配
private CustomerDao customerDao;

如果@Resource注解上添加name名称
使用@Resource注解,则按照名称注入,会到spring容器中查找customerDao的名称,对应,id的属性值,如果找到,可以匹配。
如果没有找到,抛出异常。

//第三种: JSR-250标准(jdk) 提供@Resource 
@Resource(name="customerDao")//只能按照customerDao名称进行匹配
private CustomerDao customerDao;

(4) JSR-330标准(jdk) 提供 @Inject (麻烦点)
需要先导入 javax.inject 的 jar

//第四种: JSR-330标准(jdk) 提供 @Inject ,配合@name注解
@Inject//默认按照类型注入
private CustomerDao customerDao;

//第四种: JSR-330标准(jdk) 提供 @Inject ,配合@name注解
@Inject//默认按照类型注入
@Named("customerDao")//按照名字注入,必须配合@Inject使用
private CustomerDao customerDao;

6.Bean的作用域和生命周期

6.1 bean的作用域

在这里插入图片描述

  • Singleton: 在一个spring容器中,对象只有一个实例。(默认值)
    Spring容器初始化时初始bean对象,只初始化一次
  • Prototype: 在一个spring容器中,存在多个实例,每次getBean 返回一个新的实例。
    从spring中获取bean时初始化

6.2 bean的生命周期

通过spring工厂,可以控制bean的生命周期。

6.2.1 使用xml方式

  • 通过 init-method属性 指定实例化后的调用方法
  • 通过 destroy-method属性 指定销毁对象前的方法

6.2.2 使用注解方式

  • 使用 @PostConstruct 注解, 标明初始化方法 —相当于 init-method 指定初始化方法

  • 使用 @PreDestroy 注解, 标明销毁方法 ----相当于 destroy-method 指定对象销毁方法


6.3 后处理Bean(BeanPostProcessor接口)了解

后处理Bean也称之为Bean的后处理器,作用是:在Bean初始化的前后,对Bean对象进行增强。它既可以增强一个指定的Bean,也可以增强所有的Bean,底层很多功能(如AOP等)的实现都是基于它的,Spring可以在容器中直接识别调用。


7.Bean属性的依赖注入

什么是Bean属性的注入?就是对一个对象的属性赋值。有三种方式:

  • 第一种:构造器参数注入 new Book(“金瓶梅”,15.8)
  • 第二种:setter方法属性注入(setter方法的规范需要符合JavaBean规范)
  • 第三种:接口注入

Spring 框架规范中通过配置文件配置的方式,只支持构造器参数注入和setter方法属性注入,不支持接口注入 !


8.AOP

AOP 思想: 基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !
切面:需要代理一些方法和增强代码 。

Spring AOP编程两种方式

  1. Spring 1.2 开始支持AOP编程 (传统SpringAOP 编程),编程非常复杂 ---- 更好学习Spring内置传统AOP代码
  2. Spring 2.0 之后支持第三方 AOP框架(AspectJ ),实现另一种 AOP编程 – 推荐

8.1 AOP编程底层实现机制(了解)

AOP 就是要对目标进行代理对象的创建, Spring AOP是基于动态代理的,基于两种动态代理机制:JDK动态代理CGLIB动态代理

  • JDK动态代理 : 针对目标对象的接口进行代理 ,动态生成接口的实现类 !(必须有接口)
  • Cglib动态代理: Cglib的引入为了解决类的直接代理问题(生成代理子类),不需要接口也可以代理 !

Spring AOP 优先对接口进行代理 (使用Jdk动态代理)
如果目标对象没有实现任何接口,才会对类进行代理 (使用cglib动态代理)

8.2 传统Spring AOP编程和AspectJ切面编程

传统Spring AOP编程看资料

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值