spring入门

141 阅读8分钟

Spring的核心组件包括:

  • 核心容器
  • AOP
  • 数据访问/集成
  • Web
  1. 核心容器

Spring的核心容器是其最重要的组件之一,它提供了依赖注入和控制反转的功能。在这个容器中,我们可以定义Bean,并使用注解或XML文件将其注入到其他类中。让我们深入了解Spring的核心容器是如何工作的。

1.1 ApplicationContext

Spring的ApplicationContext是Spring容器的核心。它可以读取XML文件或使用注解来定义Bean,并将它们注入到其他类中。ApplicationContext提供了一个接口,使得我们可以方便地访问应用程序中的Bean。当应用程序启动时,Spring会创建一个ApplicationContext对象,并将所有的Bean实例化。在这个过程中,Spring会执行以下几个步骤:

  • 读取Bean定义文件
  • 将Bean实例化
  • 注入Bean依赖关系
  • 返回ApplicationContext对象

让我们看一下一个简单的XML配置文件示例:

<beans>
    <bean id="customerService" class="com.example.CustomerService">
        <property name="customerDAO" ref="customerDAO"/>
    </bean>

    <bean id="customerDAO" class="com.example.CustomerDAOImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="dataSource" class="com.example.DataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>
</beans>

在这个示例中,我们定义了三个Bean:customerService、customerDAO和dataSource。customerService依赖于customerDAO,而customerDAO依赖于dataSource。当Spring读取这个XML文件时,它会实例化这三个Bean,并将它们注入到彼此之间。

1.2 BeanFactory

Spring的BeanFactory是Spring容器的基础。它是一个工厂模式的实现,它允许我们创建和管理Bean。在BeanFactory中,我们可以使用注解或XML文件定义Bean,并将它们注入到其他类中。BeanFactory也提供了一些方法,可以帮助我们获取Bean。BeanFactory的实现包括:

  • DefaultListableBeanFactory:这是Spring中最常用的BeanFactory实现。它可以从XML文件或注解中读取Bean定义,并将它们注入到其他类中。
  • XmlBeanFactory:这是一个过时的实现,用于从XML文件中读取Bean定义。它已经被DefaultListableBeanFactory替代。

1.3 Bean的生命周期

在Spring中,Bean的生命周期包括以下几个步骤:

  • 实例化:当Spring容器启动时,它会实例化所有在XML文件或注解中定义的Bean。
  • 属性赋值:Spring会为每个Bean设置它的属性,包括基本类型、引用类型和集合类型。
  • 初始化方法:在Bean实例化和属性赋值完成之后,Spring会调用Bean的初始化方法。我们可以使用@PostConstruct注解或实现InitializingBean接口来定义Bean的初始化方法。
  • 使用:当Bean实例化和初始化方法完成之后,它们就可以在其他类中使用了。
  • 销毁:当应用程序关闭时,Spring会调用Bean的销毁方法。我们可以使用@PreDestroy注解或实现DisposableBean接口来定义Bean的销毁方法。
  1. AOP

Spring的AOP(面向切面编程)是一个非常重要的组件,它允许我们在程序执行的不同阶段添加特定的逻辑。例如,我们可以在方法调用之前、之后或异常抛出时添加特定的逻辑。让我们深入了解Spring的AOP是如何工作的。

2.1 切面

在Spring的AOP中,切面是一组相关的通知(Advice)和切点(Pointcut)。通知是特定的代码,它会在切点处执行。切点是一个表达式,它定义了切面要作用的方法或类。当程序执行到切点时,切面中的通知就会被执行。

Spring的AOP支持以下类型的通知:

  • Before:在方法执行之前执行。
  • After returning:在方法执行之后返回结果时执行。
  • After throwing:在方法抛出异常时执行。
  • After:无论方法执行结果如何,都会执行。
  • Around:在方法执行前后都会执行。

2.2 代理

Spring的AOP是通过代理实现的。在代理模式中,代理对象将实际对象包装起来,并通过接口与客户端交互。在Spring的AOP中,代理对象和实际对象都实现了相同的接口。当客户端调用代理对象的方法时,代理对象会调用实际对象的方法,并在必要时添加通知。

Spring的AOP支持两种代理方式:

  • JDK动态代理:它基于Java的反射机制实现。它只能代理实现了接口的类。
  • CGLIB代理:它基于字节码生成实现。它可以代理任意类让我们来看一个简单的AOP示例。假设我们有一个接口HelloService,它有一个sayHello()方法。我们想在这个方法执行之前打印一条日志。下面是我们的代码:
public interface HelloService {
    void sayHello();
}

public class HelloServiceImpl implements HelloService {
    public void sayHello() {
        System.out.println("Hello, world!");
    }
}

public class LoggingAspect {
    public void beforeAdvice() {
        System.out.println("Executing before advice");
    }
}

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService service = (HelloService) context.getBean("helloService");
        service.sayHello();
    }
}

在上面的代码中,HelloService是我们要代理的接口。HelloServiceImpl是实现该接口的具体类。LoggingAspect是一个切面,它包含了一个前置通知(before advice),它会在sayHello()方法执行之前打印一条日志。Main是我们的启动类,它从Spring容器中获取HelloService的实例,并调用它的sayHello()方法。

下面是我们的Spring配置文件applicationContext.xml:

<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-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="helloService" class="com.example.HelloServiceImpl"/>

    <bean id="loggingAspect" class="com.example.LoggingAspect"/>

    <aop:config>
        <aop:aspect id="logging" ref="loggingAspect">
            <aop:before pointcut="execution(* com.example.HelloService.sayHello())"
                method="beforeAdvice"/>
        </aop:aspect>
    </aop:config>
</beans>

在上面的配置文件中,我们定义了一个名为helloService的Bean,并将它的类设置为HelloServiceImpl。我们还定义了一个名为loggingAspect的Bean,并将它的类设置为LoggingAspect。在aop:config元素中,我们定义了一个切面logging,它包含了一个前置通知(before advice)。这个前置通知会在执行HelloService的sayHello()方法之前执行。

运行Main类,我们将会看到以下输出:

Executing before advice
Hello, world!

这表明我们的AOP已经成功地将前置通知添加到了HelloService的sayHello()方法中。

  1. Spring MVC

Spring MVC是一个Web框架,它允许我们构建基于MVC(Model-View-Controller)的Web应用程序。在Spring MVC中,Controller接受来自客户端的请求,并调用相应的Service处理逻辑。Service再调用Dao层来访问数据库,最终将结果返回给客户端。下面是Spring MVC中的一些核心组件:

  • DispatcherServlet:是Spring MVC的核心组件,它接受所有的客户端请求,并将它们分派到合适的Controller处理。
  • HandlerMapping:将客户端请求映射到合适的Controller处理。
  • Controller:接受客户端请求,并将它们传递给Service处理逻辑。
  • Service:实现业务逻辑,并调用Dao层来访问数据库。
  • Dao:与数据库交互,执行CRUD(Create, Retrieve, Update, Delete)操作。

3.1 Spring MVC示例

下面是一个简单的Spring MVC示例,它展示了如何使用Spring MVC构建一个Web应用程序。

首先,我们需要配置web.xml文件,它是Web应用程序的入口文件。下面是web.xml文件的内容:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <display-name>Spring MVC Example</display-name>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在上面的配置文件中,我们定义了一个名为dispatcher的Servlet,并将它的类设置为org.springframework.web.servlet.DispatcherServlet。我们还指定了一个名为contextConfigLocation的初始化参数,它指向了Spring配置文件dispatcher-servlet.xml。最后,我们将dispatcher映射到所有的客户端请求。

接下来,我们需要配置dispatcher-servlet.xml文件。这个文件包含了Spring MVC的配置信息。下面是dispatcher-servlet.xml文件的内容:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="com.example"/>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

在上面的配置文件中,我们使用context:component-scan元素扫描了com.example包下的所有类,将它们自动注册为Spring Bean。我们还使用mvc:annotation-driven/元素启用了Spring MVC的注解驱动。

最后,我们配置了一个名为InternalResourceViewResolver的Bean,它将视图名称映射到JSP文件。在上面的示例中,我们将所有视图文件存储在/WEB-INF/views/目录下,并使用.jsp作为文件扩展名。

现在,我们已经完成了配置工作,可以开始编写Controller了。下面是一个简单的HomeController类,它响应根路径的请求,并返回一个简单的欢迎消息:

@Controller
public class HomeController {
 
    @RequestMapping("/")
    public String home(Model model) {
        model.addAttribute("message", "Welcome to Spring MVC!");
        return "home";
    }
 
}

在上面的示例中,我们使用@RequestMapping注解将home()方法映射到根路径。在方法体内,我们将欢迎消息存储在Model对象中,并将视图名称设置为home。当HomeController处理完请求后,DispatcherServlet会将视图名称解析为/WEB-INF/views/home.jsp文件,并将Model对象传递给该文件。

最后,我们还需要创建一个JSP文件来显示欢迎消息。下面是home.jsp文件的内容:

<html>
<head>
    <title>Spring MVC Example</title>
</head>
<body>
    <h1>${message}</h1>
</body>
</html>

在上面的示例中,我们使用EL表达式${message}来显示欢迎消息,它会自动从Model对象中获取该属性的值。

  1. 总结

Spring是一个功能强大、灵活性高的Java开发框架,它的核心是IoC容器和AOP技术。Spring可以帮助开发者降低应用程序的耦合性,提高代码的可维护性和可测试性,同时还提供了丰富的Web和数据访问支持,使得开发Web应用程序和企业级应用程序更加容易。

本文介绍了Spring的基本原理和一些核心组件,包括IoC容器、Bean、AOP、Spring MVC等。我们还通过一个简单的Spring MVC示例来演示了如何使用Spring构建Web应用程序。

总之,Spring是Java开发领域中不可或缺的框架之一,值得每一个Java开发者深入学习和使用。