1. spring前的代码
1.1 强耦合调用
Computer和Windows98强耦合调用
package com.zqq.demo1;
/**
* 电脑
*/
public class Computer {
/**
* 操作系统
*/
Windows98 windows98;
public Computer(Windows98 windows98) {
this.windows98 = windows98;
}
/**
* 工作
*/
public void work(){
this.windows98.run();
}
}
package com.zqq.demo1;
/**
* 操作系统
*/
public class Windows98 {
/**
* 运行
*/
public void run(){
System.out.println("工作在Windows98上");
}
}
package com.zqq.demo1;
public class Demo1 {
/**
* 运行电脑
* @param args
*/
public static void main(String[] args) {
Computer computer = new Computer(new Windows98());
computer.work();
}
}
1.2 接口编程解耦合
Windows98实现ComputerSystem接口
package com.zqq.demo2;
/**
* 电脑
*/
public class Computer {
/**
* 操作系统
*/
ComputerSystem computerSystem;
public Computer(ComputerSystem computerSystem) {
this.computerSystem = computerSystem;
}
/**
* 工作
*/
public void work(){
computerSystem.run();
}
}
package com.zqq.demo2;
/**
* 操作系统
*/
public interface ComputerSystem {
/**
* 运行
*/
void run();
}
package com.zqq.demo2;
/**
* 操作系统
*/
public class Windows7 implements ComputerSystem{
public void run() {
System.out.println("工作在Windows7上");
}
}
package com.zqq.demo2;
/**
* 操作系统
*/
public class Windows98 implements ComputerSystem {
/**
* 运行
*/
public void run() {
System.out.println("工作在Windows98上");
}
}
package com.zqq.demo2;
/**
* 操作系统
*/
public class Windows7 implements ComputerSystem{
/**
* 运行
*/
public void run() {
System.out.println("工作在Windows7上");
}
}
package com.zqq.demo2;
public class Demo2 {
/**
* 运行电脑
* @param args
*/
public static void main(String[] args) {
ComputerSystem computerSystem = new Windows98();
Computer computer = new Computer(computerSystem);
computer.work();
}
}
1.3 spring IOC 松耦合
在spring中配置可以完成如上main方法中的computerSystem和computer的对象的创建的配置
maven项目添加spring依赖
pom.xml
org.springframework
spring-beans
5.0.2.RELEASE
org.springframework
spring-core
5.0.2.RELEASE
org.springframework
spring-context
5.0.2.RELEASE
applicationContext.xml
package com.zqq.demo3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Spring配置测试
*/
public class Demo3 {
/**
* 电脑运行
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Computer computer = (Computer) context.getBean("computer");
computer.work();//工作在Windows7系统上
}
}
2. spring可以做什么?
Spring致力于全方位的简化JAVA开发,为降低开发成本、复杂性,采取以下四种策略:
- 基于POJO的轻量级和最小侵入性编程;
- 通过依赖注入和面向切面接口实现松耦合;
- 基于切面和惯例进行声明式编程;
- 通过切面和模板减少样板式代码;
2.1 Spring装配Bean
Spring装配Bean对象的三种方式:
- XML配置
- 自动化装配(注解)
- Java代码装配(@Configuation)
2.1.1 XML配置
见1.3
2.1.2 自动化装配(注解)
package com.zqq.demo4;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
* 电脑
*/
@Component
public class Computer {
/**
* 操作系统
*/
@Qualifier("windows7")
@Autowired
private ComputerSystem computerSystem;
/**
* 工作
*/
public void work(){
computerSystem.run();
}
}
package com.zqq.demo4;
/**
* 操作系统
*/
public interface ComputerSystem {
/**
* 运行
*/
public void run();
}
package com.zqq.demo4;
import org.springframework.stereotype.Component;
/**
* 操作系统
*/
@Component
public class Windows7 implements ComputerSystem {
/**
* 运行
*/
public void run() {
System.out.println("运行在Windows7上");
}
}
package com.zqq.demo4;
import org.springframework.stereotype.Component;
/**
* 操作系统
*/
@Component
public class Windows98 implements ComputerSystem {
/**
* 运行
*/
public void run() {
System.out.println("运行在Windows98上");
}
}
package com.zqq.demo4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Spring注解测试
*/
public class Demo4 {
/**
* 电脑运行
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
Computer computer = (Computer) context.getBean("computer");
computer.work();//运行在Windows7上
}
}
2.1.3
package com.zqq.demo5;
/**
* 电脑
*/
public class Computer {
/**
* 操作系统
*/
ComputerSystem computerSystem;
public Computer(ComputerSystem computerSystem) {
this.computerSystem = computerSystem;
}
/**
* 工作
*/
public void work(){
computerSystem.run();
}
}
package com.zqq.demo5;
/**
* 操作系统
*/
public interface ComputerSystem {
/**
* 运行
*/
void run();
}
package com.zqq.demo5;
/**
* 操作系统
*/
public class Windows7 implements ComputerSystem {
/**
* 运行
*/
public void run() {
System.out.println("运行在Windows7上");
}
}
package com.zqq.demo5;
/**
* 操作系统
*/
public class Windows98 implements ComputerSystem{
/**
* 运行
*/
public void run() {
System.out.println("运行在Windows98上");
}
}
package com.zqq.demo5;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Java代码配置
*/
@Configuration
public class SystemConfig {
@Bean
public ComputerSystem computerSystem(){
return new Windows7();
}
@Bean
public Computer computer(){
return new Computer(computerSystem());
}
}
package com.zqq.demo5;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Spring Java代码装配
*/
public class Demo5 {
/**
* 电脑工作
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SystemConfig.class);
Computer computer = (Computer) context.getBean("computer");
computer.work();
}
}
2.2 Spring注解
- @Controller:控制器;
- @Autowired:自动装配成员变量,@Autowired(required=false) 在找不到匹配Bean时也不报错;
- @Qualifier:注释指定注入bean的名称,防止冲突。
- @Component:定义一个bean;
- @Service:定义一个service bean;
- @Scope:设置bean的类型;
- @Repository:定义一个bean,可将该对象中抛出的数据访问异常封装为Spring的数据访问异常。
2.3 Spring依赖注入
@Autowired
以下均可使用
- 成员变量注入
- 构造方法注入
- 设值方法注入
xml配置
同上
2.4 Bean的作用域 Scope
这个链接写得很详细
https://www.jianshu.com/p/fcdcbaace675
- singleton(单例):在整个应用中,只创建bean的一个实例;
value=ConfigurableBeanFactory.SCOPE_SINGLETON
- prototype(原型):每次注入或者通过Spring上下文获取时,都会创建一个新的bean实例;
value=ConfigurableBeanFactory.SCOPE_PROTOTYPE
- session(会话):在web应用中,为每一个会话创建一个bean实例;
value=WebApplicationContext.SCOPE_SESSION
- request(请求):在web应用中,为每一个请求创建一个bean实例。
value=WebApplicationContext.SCOPE_REQUEST
备注:当bean的作用域设置为session或request时,需要配置proxyMode的值为:interfaces。
2.5 AOP
相关术语
- 通知(Advice)
通知定义了切面是什么及何时使用。除了描述切面要完成的工作(日志记录),通知还决定了何时执行。
- 前置通知(Befor):目标方法调用前调用通知;
- 后置通知(After):目标方法调用后调用通知;
- 返回通知(After-returning):目标方法返回成功后调用通知;
- 异常通知(After-throwing):目标方法抛出异常后调用通知;
- 环绕通知(Around):目标方法调用前与调用后都会调用通知;
- 连接点(Join point)
连接点是指在应用执行过程中能够插入切面的一个点(调用方法时)。 - 切点(Poincut)
切点定义了何处使用通知。定义匹配通知所要织入的一个或多个连接点。通常使用明确的类和方法名,或是利用正则表达式匹配。 - 切面(Aspect)
切面就是通知和切点的结合。
织入(Weaving)
把切面应用到目标对象,并创建新的代理对象的过程。 - 织入
3种实现方式
- 基于代理的经典Spring AOP;
- 纯POJO切面;
- @AspectJ注解驱动切面;
2.5.1 基于代理的经典Spring AOP
package com.zqq.demo6;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 切点方法前执行
*/
@Component
public class AopBefore implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("Before the system work ,do something");
}
}
package com.zqq.demo6;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 切点方法前执行
*/
@Component
public class AopBefore implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("Before the system work ,do something");
}
}
package com.zqq.demo6;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 切点方法后执行
*/
@Component
public class AopAfter implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("after the system,do something");
}
}
package com.zqq.demo6;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
/**
* 电脑
*/
@Component
public class Computer {
/**
* 操作系统
*/
@Qualifier("systemProxy")
@Autowired
private ComputerSystem computerSystem;
/**
* 工作
*/
public void work(){
computerSystem.run();
}
}
package com.zqq.demo6;
/**
* 操作系统
*/
public interface ComputerSystem {
/**
* 运行
*/
void run();
}
package com.zqq.demo6;
import org.springframework.stereotype.Component;
/**
* 操作系统
*/
@Component
public class Windows7 implements ComputerSystem {
/**
* 运行
*/
public void run() {
System.out.println("运行在Windows7上");
}
}
com.zqq.demo6.ComputerSystem
aopBefore
aopAfter
package com.zqq.demo6;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Spring注解测试
*/
public class Demo6 {
/**
* 电脑运行
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext6.xml");
Computer computer = (Computer) context.getBean("computer");
computer.work();
}
}
2.5.3
package com.zqq.demo7;
import org.springframework.stereotype.Component;
/**
* AOP
*/
@Component
public class AopDemo {
/**
* 方法前执行
*/
public void before(){
System.out.println("before method");
}
/**
* 方法后执行
*/
public void after(){
System.out.println("after method");
}
}