Spring学习笔记 ——入门

Spring是什么

首先Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

也就是说,我们学习Spring是学习其理念思想也就是IoC和AOP。其适用范围很广,以至于任何应用都能从中受益。

Spring的优势

  • 低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
  • 声明式事务管理(基于切面和惯例)
  • 方便集成其他框架(如MyBatis、Hibernate)
  • 降低 Java 开发难度
  • Spring 框架中包括了 J2EE 三层的每一层的解决方案(一站式)

Spring框架结构

Spring

一些概念

  • pojo即 Plain Old Java Objects,简单老式 Java 对象
  • JavaBean即符合 JavaBean 规范的 Java 类。JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。

IoC

IoC:Inverse of Control(控制反转)

  • 读作“反转控制”,更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
  • 正控:若要使用某个对象,需要自己去负责对象的创建
  • 反控:若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架
  • 好莱坞法则:Don’t call me ,I’ll call you

一个常见的例子
传统方法:
传统构建对象方式
对于传统模式,我们有这样代码实现

Juice juice = new Juice("橙子","多糖","超大杯");

工厂模式:
工厂模式
同样的,我们有如下的代码实现:

Shop shop = new Shop("橙子","多糖","超大杯");
Juice juice = Shop.makeJuice();

事实上对于这样简单的类,我们不需要引入工厂模式来增加复杂度,但是对于更加复杂的类(假如橙子,糖都是一个比较复杂的类),我们使用工厂的话会减少代码的管理成本。

先记住这个例子,我们编写一个简单的Spring程序。

首先编写一个pojo(传统对象)

package pojo;

public class Source {  
    private String fruit;   // 类型
    private String sugar;   // 糖分描述
    private String size;    // 大小杯    
    /* setter and getter */
}

编写配置文件装配bean

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
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">
 <bean name="source" class="pojo.Source">
 	<property name="fruit" value="橙子"/> 
  	<property name="sugar" value="多糖"/>
  	<property name="size" value="超大杯"/>
 </bean>
</beans>

接着来试一下Spring

ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[]{"applicationContext.xml"}
);

Source source = (Source) context.getBean("source");
System.out.println(source.getFruit());
System.out.println(source.getSugar());
System.out.println(source.getSize());

输出如下:
输出
(我们的工程文件结构如下)
在这里插入图片描述
(如何创建Spring工程?)
我们使用IDEA
在这里插入图片描述
在这里插入图片描述
这样就获得了一个包含Spring环境的工程。

AOP

如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用

AOP 即 Aspect Oriented Program 面向切面编程
首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。

  • 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
  • 所谓的周边功能,比如性能统计,日志,事务管理等等
    周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面

在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 “编织” 在一起,这就叫AOP

AOP 当中的概念:

  • 切入点(Pointcut) 在哪些类,哪些方法上切入(where)
  • 通知(Advice) 在方法执行的什么实际(when:方法前/方法后/方法前后)做什么(what:增强的功能)
  • 切面(Aspect) 切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!
  • 织入(Weaving) 把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)

AOP 编程

我们还是采用配置文件的方式来进行一个演示

首先我们编写核心功能:

package service;

public class ProductService {
    public void doSomeService(){
        System.out.println("doSomeService");
    }
}

还有周边功能

package aspect;
//这里的依赖包需要额外安装,建议看这个教程:https://blog.csdn.net/shuduti/article/details/53069241
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggerAspect {
    
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("start log:" + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();
        System.out.println("end log:" + joinPoint.getSignature().getName());
        return object;
    }
}

按照IoC的方式进行配置文档编辑

<?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"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean name="productService" class="service.ProductService" />
    <bean id="loggerAspect" class="aspect.LoggerAspect"/>
</beans>

编写测试方法

@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext(
            new String[]{"applicationContext.xml"}
    );
    ProductService productService = (ProductService) context.getBean("productService");
    productService.doSomeService();
}

运行
在这里插入图片描述
接下来,就是本节重点

我们使用AOP来切入

我们希望以doSomeService()为切入点,在其执行前后增强日志功能

这样配置

<?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"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean name="productService" class="service.ProductService" />
    <bean id="loggerAspect" class="aspect.LoggerAspect"/>

    <!-- 配置AOP -->
    <aop:config>
        <!-- where:在哪些地方(包.类.方法)做增加 -->
        <aop:pointcut id="loggerCutpoint"
                      expression="execution(* service.ProductService.*(..)) "/>

        <!-- what:做什么增强 -->
        <aop:aspect id="logAspect" ref="loggerAspect">
            <!-- when:在什么时机(方法前/后/前后) -->
            <aop:around pointcut-ref="loggerCutpoint" method="log"/>
        </aop:aspect>
    </aop:config>
</beans>

运行:
在这里插入图片描述
我们获得了日志功能,但是没有修改业务代码

发布了14 篇原创文章 · 获赞 0 · 访问量 760

猜你喜欢

转载自blog.csdn.net/weixin_43819675/article/details/103958271