1. Spring 核心之 IoC 控制翻转

IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控 制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控 制权发生了反转,这就是 Spring 的 IoC 思想。

1.1 入门案例

1.1.1 使用 Spring 容器创建对象

配置文件中进行配置

1.1.2 获取 Spring 容器

有两种

BeanFactory

是基础类型的 IoC 容器,是一个管理 Bean 的工厂

ApplicationContext

是 BeanFactory 的子接口,也被称为应用上下文

  • classPathXmlApplicationContext(从类路径中寻找指定的 XML 配置文件)
  • FileSystemXmlApplicationContext (可以获取类路径之外的资源)

1.1.3 获取非自定义对象

1.1.4 bean 标签的属性

属性 说明
class 指定bean对应类的全路径
name name是bean对应对象的一个标识
scope 执行bean对象创建模式和生命周期,scope=”singleton”和scope=”prototype

“ | | id | id是bean对象的唯一标识,不能添加特别字符 | | lazy-init | 是否延时加载 默认值:false。true 延迟加载对象,当对象被调用的时候才会加载,测试 的时候,通过getbean()方法获得对象。 | | init-method | 只需要加载配置文件即可对象初始化方法 | | destroy-method | 对象销毁方法 |

scope

  • singleton:单例;容器启动完毕之后单例对象就被创建了,而且容器中只有唯一的一个对象。
  • prototype:多例;多例的对象是什么时候使用什么时候去创建,每次获取的时候都创建新对象。

lazy-init (针对单例)

  • true:获取对象的时候才去创建对象
  • false:立即创建对象,不管是否使用

1.2 Spring 容器创建对象的方式

1.2.1 默认的构造方法

1.2.2 带参数的构造方法

1.2.3 使用工厂类

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">











创建对象

1.3 基于 XML 的DI


DI—Dependency Injection,即“依赖注入”

1.3.1 通过 set 方法





1.3.2 通过构造方法





1.3.3 自动注入


对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签 设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。根据 自动注入判断标准的不同,可以分为两种:

  • byName
  • byType


配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用 者 bean 类的某引用类型属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。但这样 的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

1.4 基于注解实现 IoC

1.4.1 声明 Bean 注解


在类上添加注解 @Component 表示该类创建对象的权限交给 Spring 容器。注解的value属性用于指定 bean 的 id 值,value 可以省略。

除此之外:

  • @Repository : 用于dao实现类的的注解
  • @Service: 用户service实现类的注解
  • @Controller: 用于controller实现类的注解

    这三个注解与 @Component 都可以创建对象,但这三个注解还有其他的含义,@Service 创建业务层对 象,业务层对象可以加入事务功能,@Controller 注解创建的对象可以作为处理器接收用户的请求。



1.4.2 包扫描


1.4.3 属性注入 @value

使用该注解完成属性注入 时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

@Value(“巴萨罗纳”)
private String name;
@Value(“1004”)
private Integer id;
@Value(“巴萨罗纳”)
private String address;

1.4.4 byType 自动注入 @Autowired

需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。使用该注解完 成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

@Autowired(required = true)//自动装配
private StuDao stuDao;

1.4.5 byName 自动注入 @Autowired 和 @Qualifier

@Autowired(required = true)//自动装配
@Qualifier(“stuDao”)
private StuDao stuDao;

1.4.6 @Resource 自动注入

Spring提供了对 jdk中@Resource注解的支持。@Resource 注解既可以按名称匹配Bean,也可以按类


2. Spring 核心之 AOP

Aspect Oriented Programming , 面向切面编程,是通过预编译方式和运行期动态 代理实现程序功能的统一维护的一种技术。


AOP的作用:不修改源码的情况下,程序运行期间对方法进行功能增强
好处:

  • 减少代码的重复,提高开发效率,便于维护。
  • 专注核心业务的开发。

核心业务和服务性代码混合在一起

2.1 AOP 实现机制

代理:自己不做,找别人帮忙。
代理模式:在一个原有功能的基础之上添加新的功能。
分类:

  • 静态代理
  • 动态代理

2.2 静态代理

  • 基于类(继承)
  • 基于接口
  • 提取出切面代码,作为 AOP 接口

总结静态代理:
2)缺点:

  • 因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。
  • 一旦接口增加方法,目标对象与代理对象都要维护。

2.3 动态代理

动态代理:程序运行的时候,根据要被代理的对象动态生成代理类。

  • 基于 JDK

public static void main(String[] args) {
// 被代理的对象
IService service1 = new Service1();

  1. // 返回代理对象, 基于 JDK 的代理<br /> **IService iService = (IService) Proxy.**_**newProxyInstance**_**(**<br /> service1.getClass().getClassLoader(),<br /> service1.getClass().getInterfaces(),<br /> new InvocationHandler() { // 回调函数 句柄 代理规则的地方<br /> @Override<br /> public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br /> try {<br /> System._out_.println("开始事务");<br /> Object invoke = method.invoke(service1, args);<br /> System._out_.println("提交事务");<br /> return invoke;<br /> } catch (Exception e){<br /> e.printStackTrace();<br /> System._out_.println("回滚事务");<br /> throw e;<br /> } finally {<br /> System._out_.println("finally ------");<br /> }<br /> }<br /> }<br /> );<br /> iService.add();<br />}
  • 基于 CGLIB

public static void main(String[] args) {
// 没有接口的目标对象
Football f1 = new Football();
// 选择 cglib 进行对象代理
Football temp = (Football) Enhancer.create(
f1.getClass(),
new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
try {
System.out.println(“开始事务”);
//核心位置
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println(“提交事务”);
return invoke;
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println(“处理异常”);
throw throwable;
} finally {
System.out.println(“ finally ———“);
}
}
}
);
temp.add(“皇家马德里”);
}

2.4 Spring AOP

Spring的AOP实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分 进行代码编写,并通过配置的方式完成指定目标的方法增强。
相关术语:

  • Target
  • Proxy
  • Aspect
  • Joinpoint
  • Poincut
  • Advice
  • Weaving

2.4.1 AspectJ 对 AOP 的实现

通知类型(5 种):

  • 前置
  • 后置
  • 环绕
  • 异常
  • 最终

切入点表达式


3. Spring 事务管理