1. Spring 核心之 IoC 控制翻转
IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控 制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控 制权发生了反转,这就是 Spring 的 IoC 思想。
1.1 入门案例
1.1.1 使用 Spring 容器创建对象
配置文件中进行配置
1.1.2 获取 Spring 容器
BeanFactory
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 使用工厂类
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();
// 返回代理对象, 基于 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 种):
- 前置
- 后置
- 环绕
- 异常
- 最终
切入点表达式
