背景
- JavaEE 应用框架
- 基于IOC和AOP的结构J2EE系统的框架
- IOC(反转控制):即创建对象由以前的程序员自己new 构造方法来调用,变成了交由Spring创建对象,是Spring的基础
- DI(依赖注入):拿到的对象的属性,已经被注入好相关值了,直接使用即可
- AOP(Aspect Oriented Program 面向切面编程)
- 功能分为核心业务功能(登录、增删改查)和周边功能(性能统计、日志、事务管理)
- 周边功能在Spring的面向切面编程AOP思想里,即被定义为切面
- 面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发
- 然后把切面功能和核心业务功能 "编织" 在一起
IOC/DI
- 新建项目
- 添加依赖jar包
- 准备 pojo
- 配置 applicationContext.xml
Catagory.java
1 package com.how2java.pojo; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("c") 6 public class Category { 7 8 public int getId() { 9 return id; 10 } 11 public void setId(int id) { 12 this.id = id; 13 } 14 public String getName() { 15 return name; 16 } 17 public void setName(String name) { 18 this.name = name; 19 } 20 private int id; 21 private String name = "catagory 1"; 22 }
Product.java
1 package com.how2java.pojo; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Component; 5 6 @Component("p") 7 public class Product { 8 private int id; 9 private String name = "product 1"; 10 11 @Autowired 12 private Category category; 13 public int getId() { 14 return id; 15 } 16 public void setId(int id) { 17 this.id = id; 18 } 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 public Category getCategory() { 26 return category; 27 } 28 public void setCategory(Category category) { 29 this.category = category; 30 } 31 }
TestSpring.java
1 package com.how2java.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.how2java.pojo.Product; 7 8 public class TestSpring { 9 10 public static void main(String[] args) { 11 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" }); 12 13 Product p = (Product) context.getBean("p"); 14 System.out.println(p.getName()); 15 System.out.println(p.getCategory().getName()); 16 } 17 }
applicationContext.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation=" 6 http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 10 http://www.springframework.org/schema/tx 11 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 12 http://www.springframework.org/schema/context 13 http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 14 15 <context:annotation-config/> 16 <bean name="c" class="com.how2java.pojo.Category"> 17 <property name="name" value="category 1" /> 18 </bean> 19 <bean name="p" class="com.how2java.pojo.Product"> 20 <property name="name" value="product1" /> 21 <!-- <property name="category" ref="c" /> --> 22 </bean> 23 24 </beans>
AOP
- 辅助功能和核心业务功能彼此独立开发
- “登录”功能没有“性能统计”和“日志输出”也可以正常运行
- 如果有需要就把“日志输出”和“登录”功能编制在一起,实现登录时看到日志输出
- 辅助功能叫做切面,这种选择性的,低耦合的把切面和核心业务功能结合在一起的编程思想,就叫AOP
ProductService.java
1 package com.how2java.service; 2 3 public class ProductService { 4 public void doSomeService() { 5 System.out.println("doSomeService"); 6 } 7 }
LoggerAspect.java
1 package com.how2java.aspect; 2 3 import org.aopalliance.intercept.Joinpoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class LoggerAspect { 7 public Object log(ProceedingJoinPoint joinPoint) throws Throwable{ 8 System.out.println("start log:" + joinPoint.getSignature().getName()); 9 Object object = joinPoint.proceed(); 10 System.out.println("end log:" + joinPoint.getSignature().getName()); 11 return object; 12 } 13 }
TestSpring.java
1 package com.how2java.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.how2java.service.ProductService; 7 8 public class TestSpring { 9 public static void main(String[] args) { 10 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" }); 11 ProductService s = (ProductService) context.getBean("s"); 12 s.doSomeService(); 13 } 14 }
applicationContext.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xsi:schemaLocation=" 8 http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 10 http://www.springframework.org/schema/aop 11 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 12 http://www.springframework.org/schema/tx 13 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 14 http://www.springframework.org/schema/context 15 http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 16 17 <bean name="s" class="com.how2java.service.ProductService"> 18 </bean> 19 20 <bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/> 21 22 <aop:config> 23 <aop:pointcut id="loggerCutpoint" 24 expression= 25 "execution(* com.how2java.service.ProductService.*(..))"/> 26 27 <aop:aspect id="logAspect" ref="loggerAspect"> 28 <aop:around pointcut-ref="loggerCutpoint" method="log"/> 29 </aop:aspect> 30 </aop:config> 31 32 </beans>
- 通过xml文件配置的方式,把日志记录功能(切面)和核心业务编织在了一起,而TestSpring代码没有发生任何变化(解耦)
参考
Spring DI原理
https://www.cnblogs.com/gudazhi/p/11088439.html
Spring的IOC原理
https://www.cnblogs.com/superjt/p/4311577.html
步骤