第一部分:Spring基础
文章目录
- 第一部分:Spring基础
- 一、核心概念
- 1.什么是Spring?
- 2.Spring架构
- 3.Spring优势
- 二、控制反转
- 1.为什么要控制反转?
- 2.组件化方式编程案例(Test01_di)
- 3.采用组件化思维,装配打印机(Test01_di)
- 三、面向切面编程(AOP)方面编程
- 1.什么是AOP?
- 2.如何实现AOP?
- 3. 使用 AOP 实现日志处理( Test02_aop )
一、核心概念
- 控制反转(
IOC:Inversion of Control
)/依赖注入(DI:Dependency Injection
) - AOP(Aspect Oriented Programming)
1.什么是Spring?
Spring:轻量级集成框架
设计目标:使现有技术更加易用,推进编码最佳实践
设计理念:Spring是面向 Bean 的编程
内容
- IOC容器
- AOP实现
- 数据访问支持
- 简化JDBC/ORM框架
- 声明式事务
web集成
2.Spring架构
3.Spring优势
- 低侵入设计
- 独立于各种应用服务器
- 依赖注入特性将组件关系透明化,降低了耦合度
- 面向切面编程特性允许将通用任务进行集中式处理
- 与第三方框架的良好整合
二、控制反转
控制反转:将创建对象的"控制"反转给容器。程序从容器中获取对象。
1.为什么要控制反转?
根本目标:实现系统的易维护、可插拔
首先,将组件对象的控制权从代码本身转移到外部容器,要求:
- 解耦合。实现每个组件时只关注组件内部的事情
- 采用组件化的思想:分离关注点,使用接口,不再关注实现
- 依赖的注入:将组件的构建和使用分开
- 要点:明确定义组件间的接口
2.组件化方式编程案例(Test01_di)
1.加包
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.13.RELEASE</spring.version>
<log4j.version>1.2.17</log4j.version>
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
2.定义问候类
package com.by.entity;
public class HelloSpring {
// 问候的内容
private String content;
public HelloSpring() {
}
public void hello(){
System.out.println("Hello, " + content);
}
// setter/getter
3.添加配置文件di.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置 bean 对象-->
<bean id="helloSpring" class="com.by.entity.HelloSpring">
<property name="content" value="IoC"></property>
</bean>
</beans>
4.测试类
package com.by;
import static org.junit.Assert.assertTrue;
import com.by.entity.HelloSpring;
import com.by.entity.Saying;
import com.by.printer.Printer;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppTest
{
public void test01_simple(){
ApplicationContext ac = new ClassPathXmlApplicationContext("di.xml");
HelloSpring hs = (HelloSpring)ac.getBean("helloSpring");
hs.hello();
((ClassPathXmlApplicationContext) ac).close();
}
3.采用组件化思维,装配打印机(Test01_di)
- 创建 maven 项目,并加包(如上例)
- 面向接口方式创建打印机,包括:墨盒接口和实现类;纸张接口和实现类(见
JavaOOP 接口) - 创建 resources/di.xml 文件装配打印机
<!--案例:Printer-->
<bean id="a4" class="com.by.printer.paper.A4Paper"></bean>
<bean id="b5" class="com.by.printer.paper.B5Paper"></bean>
<bean id="black" class="com.by.printer.ink.BlackInk"></bean>
<bean id="color" class="com.by.printer.ink.ColorInk"></bean>
<bean id="printer" class="com.by.printer.Printer">
<property name="ink" ref="black"></property>
<property name="paper" ref="a4"></property>
</bean>
- 测试。
@Test
public void test03_printer(){
ApplicationContext ac = new ClassPathXmlApplicationContext("di.xml");
Printer printer = (Printer)ac.getBean("printer");
printer.print();
}
三、面向切面编程(AOP)方面编程
1.什么是AOP?
方面:是指程序中的某些琐碎而又必须完成的工作。比如:日志、事务管理、安全认证等
等。它们散布在程序的各个角落,但又必须做,不可或缺。
AOP(Aspect Oreinted Programming):就是将分散在程序中的工作,例如:日志、安
全、事务管理等(方面),将这些工作从业务中分离出来,进行一次性处理。
2.如何实现AOP?
AOP 的目标:让我们可以“专心做事”
AOP 原理:将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决。采用 代
理机制 组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能
所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情
况下给程序动态添加功能的技术
3. 使用 AOP 实现日志处理( Test02_aop )
1.加包aspectj
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
2.业务逻辑方法
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
}
// setter/getter 略
}
package com.by.service;
import com.by.entity.User;
public class UserService {
// 添加用户
public int addUser(User user){
System.out.println("插入用户 User:" + user);
return 1;
}
}
3.定义日志增强功能 LoggerAdvice
package com.by.advice;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import java.util.Arrays;
// 日志增强
public class LoggerAdvice {
private static Logger logger = Logger.getLogger(LoggerAdvice.class);
// 前置增强
public void before(JoinPoint jp){
logger.debug("前置增强:调用 " + jp.getTarget() + " 的 " + jp.getSignature(
Arrays.toString(jp.getArgs()));
}
// 后置增强
public void afterReturning(JoinPoint jp, Object ret){
logger.debug("后置增强:调用 " + jp.getTarget() + " 的 " + jp.getSignature(
Arrays.toString(jp.getArgs()) + ",结果:" + ret);
}
}
4.配置增强 di.xml
<!--业务逻辑类-->
<bean id="userService" class="com.by.service.UserService"></bean>
<!--增强类-->
<bean id="loggerAdvice" class="com.by.advice.LoggerAdvice"></bean>
<!--增强配置类-->
<aop:config>
<aop:pointcut id="service" expression="execution(public * com.by.service..*.*(..))
<aop:aspect ref="loggerAdvice">
<aop:before method="before" pointcut-ref="service"></aop:before>
<aop:after-returning method="afterReturning" pointcut-ref="service" returning
</aop:aspect>
</aop:config>
5.测试。直接运行业务方法,可看到增强的结果。
@Test
public void test_aop(){
ApplicationContext ac = new ClassPathXmlApplicationContext("di.xml");
UserService userService = (UserService)ac.getBean("userService");
User user = new User(1000, "石头", 30);
userService.addUser(user);
System.out.println("-------------------------------------------------------");
userService.delete(1000);
}