Spring +Spring MVC+MyBatis框架

Spring 作用于:

容器
提供了对多种技术的支持
JMS
MQ支持
UnitTest
Spring是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在已经不知应用于企业应用。
是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
从大小与开销两方面而言Spring都是轻量级的。
通过控制反转(IoC)的技术达到松耦合的目的。
提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发

Spring体系结构

在这里插入图片描述

  1. Data Access/Integration(数据访问/集成):
    数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。
    JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
    ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
    OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
    JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
    Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。
  2. Web 模块:
    Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。
    Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
    Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
    Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
    Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。
  3. Core Container(核心容器):
    Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。
    Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
    Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
    Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
    Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。
  4. 其他模块:
    Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。
    AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
    Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
    Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
    Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。

Spring Jar包下载: http://repo.spring.io/simple/libs-release-local/org/springframework/spring/
使用 Spring 框架时,只需将 Spring 的四个基础包以及 commons-logging-1.2.jar 包复制到项目的 lib 目录,并发布到类路径中即可。

Spring ioC容器(控制反转)

思想:
IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IoC 思想。

Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext
BeanFactory:
BeanFactory 是基础类型的 IoC 容器,它由 org.springframework.beans.facytory.BeanFactory 接口定义,并提供了完整的 IoC 服务支持。简单来说,BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。
ApplicationContext:
ApplicationContext 是 BeanFactory 的子接口,也被称为应用上下文。该接口的全路径为 org.springframework.context.ApplicationContext,它不仅提供了 BeanFactory 的所有功能,还添加了对 i18n(国际化)、资源访问、事件传播等方面的良好支持。

需要注意的是,BeanFactory 和 ApplicationContext 都是通过 XML 配置文件加载 Bean 的。

二者的主要区别在于,如果 Bean 的某一个属性没有注入,则使用 BeanFacotry 加载后,在第一次调用 getBean() 方法时会抛出异常,而 ApplicationContext 则在初始化时自检,这样有利于检查所依赖的属性是否注入。

通常在 Java 项目中,会采用通过 ClassPathXmlApplicationContext 类实例化 ApplicationContext 容器的方式,而在 Web 项目中,ApplicationContext 容器的实例化工作会交由 Web 服务器完成。Web 服务器实例化 ApplicationContext 容器通常使用基于 ContextLoaderListener 实现的方式,它只需要在 web.xml 中添加如下代码:

<!--指定Spring配置文件的位置,有多个配置文件时,以逗号分隔-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!--spring将加载spring目录下的applicationContext.xml文件-->
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

**

第一个Spring程序

**
1、创建项目 导入相应的项目jar包
2、创建PersonDao接口
在项目的 src 目录下创建一个名为 com.mengma.ioc 的包,然后在该包中创建一个名为 PersonDao 的接口,并在接口中添加一个 add() 方法,如下所示。

   package com.mengma.ioc;
public interface PersonDao {
    public void add();
}

3、创建接口实现类PersonDaoImpl
在 com.mengma.ioc 包下创建 PersonDao 的实现类 PersonDaoImpl,编辑后如下所示。

package com.mengma.ioc;
public class PersonDaoImpl implements PersonDao {
    @Override
    public void add() {
        System.out.println("save()执行了...");
    }
}

4、创建Spring配置文件
在 src 目录下创建 Spring 的核心配置文件 applicationContext.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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 由 Spring容器创建该类的实例对象 -->
    <bean id="personDao" class="com.mengma.ioc.PersonDaoImpl" />
</beans>

注:
上述代码中,第 2~5 行代码是 Spring 的约束配置,第 7 行代码表示在 Spring 容器中创建一个 id 为 personDao 的 bean 实例,其中 id 表示文件中的唯一标识符,class 属性表示指定需要实例化 Bean 的实全限定类名(包名+类名)。

需要注意的是,Spring 的配置文件名称是可以自定义的,通常情况下,都会将配置文件命名为 applicationContext.xml(或 bean.xml)。

5、编写测试类
在 com.mengma.ioc 包下创建测试类 FirstTest,并在该类中添加一个名为 test1() 的方法,编辑后如下所示。

package com.mengma.ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class FirstTest {
    @Test
    public void testl() {
        // 定义Spring配置文件的路径
        String xmlPath = "applicationContext.xml";
        // 初始化Spring容器,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 通过容器获取personDao实例
        PersonDao personDao = (PersonDao) applicationContext
                .getBean("personDao");
        // 调用 personDao 的 add ()方法
        personDao.add();
    }
}

注:
上述代码中,首先定义了 Spring 配置文件的路径,然后创建 Spring 容器,接下来通过 Spring 容器获取了 personDao 实例,最后调用实例的 save() 方法。

6、运行项目并查看结果
使用 JUnit 测试运行 test1() 方法
在这里插入图片描述

Spring DI (依赖注入)的实现方式: 属性注入和构造注入

1、属性 setter 注入

指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。
2、构造方法注入

指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。

Spring容器实现依赖注入案例:
1、创建PersonService接口

package com.mengma.ioc;
public interface PersonService {
    public void addPerson();
}

2、创建接口实现类 PersonServiceImpl

package com.mengma.ioc;
public class PersonServiceImpl implements PersonService {
    // 定义接口声明
    private PersonDao personDao;
    // 提供set()方法,用于依赖注入
    public void setPersonDao(PersonDao personDao) {
        this.personDao = personDao;
    }
    // 实现PersonService接口的方法
    @Override
    public void addPerson() {
        personDao.add(); // 调用PersonDao中的add()方法
        System.out.println("addPerson()执行了...");
    }
}

注:
上述代码中,首先声明了 personDao 对象,并为其添加 setter 方法,用于依赖注入,然后实现了 PersonDao 接口的 addPerson() 方法,并在方法中调用 save() 方法和输出一条语句。

3、在applicationContext.xml中添加配置信息
在 applicationContext.xml 配置文件中添加一个 元素,用于实例化 PersonServiceImpl 类,并将 personDao 的实例注入到 personService 中

<bean id="personService" class="com.mengma.ioc.PersonServiceImpl">
    <!-- 将personDao实例注入personService实例中 -->
    <property name="personDao" ref="personDao"/>
</bean>

4、编写测试方法
在 FirstTest 类中创建一个名为 test2() 的方法

@Test
public void test2() {
    // 定义Spring配置文件的路径
    String xmlPath = "applicationContext.xml";
    // 初始化Spring容器,加载配置文件
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            xmlPath);
    // 通过容器获取personService实例
    PersonService personService = (PersonService) applicationContext
            .getBean("personService");
    // 调用personService的addPerson()方法
    personService.addPerson();
}

5、运行并查看结果
使用 JUnit 测试运行 test2() 方法
在这里插入图片描述

Spring Bean的配置及常用属性

作为 Spring 核心机制的依赖注入,改变了传统的编程习惯,对组件的实例化不再由应用程序完成,转而交由 Spring 容器完成,在需要时注入应用程序中,从而对组件之间依赖关系进行了解耦。这一切都离不开 Spring 配置文件中使用的 元素。

Spring 容器可以被看作一个大工厂,而 Spring 容器中的 Bean 就相当于该工厂的产品。如果希望这个大工厂能够生产和管理 Bean,这时则需要告诉容器需要哪些 Bean,以及需要以何种方式将这些 Bean 装配到一起。

Spring 配置文件支持两种不同的格式,分别是 XML 文件格式和 Properties 文件格式。

通常情况下,Spring 会以 XML 文件格式作为 Spring 的配置文件,这种配置方式通过 XML 文件注册并管理 Bean 之间的依赖关系。

XML 格式配置文件的根元素是 ,该元素包含了多个 子元素,每一个 子元素定义了一个 Bean,并描述了该 Bean 如何被装配到 Spring 容器中。

定义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" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 使用id属性定义person1,其对应的实现类为com.mengma.person1 -->
    <bean id="person1" class="com.mengma.damain.Person1" />
    <!--使用name属性定义person2,其对应的实现类为com.mengma.domain.Person2-->
    <bean name="Person2" class="com.mengma.domain.Person2"/>
</beans>

注:在上述代码中,分别使用 id 和 name 属性定义了两个 Bean,并使用 class 元素指定了 Bean 对应的实现类。

Spring 实例化Bean的三种方法

构造器实例化:
1、创建项目并导入Jar包
2、创建实体类

package com.mengma.instance.constructor;
public class Person1 {
}

3、创建Spring配置文件

<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="person1" class="com.mengma.instance.constructor.Person1" />
</beans>

注:在上述配置中,定义了一个 id 为 person1 的 Bean,其中 class 属性指定了其对应的类为 Person1。

4、创建测试类

package com.mengma.instance.constructor;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest1 {
    @Test
    public void test() {
        // 定义Spring配置文件的路径
        String xmlPath = "com/mengma/instance/constructor/ApplicationContext.xml";
        // 初始化Spring容器,加载配置文件,并对bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 通过容器获取id为person1的实例
        System.out.println(applicationContext.getBean("person1"));
    }
}

注:上述文件中,首先在 test() 方法中定义了 Spring 配置文件的路径,然后 Spring 容器会加载配置文件。在加载的同时,Spring 容器会通过实现类 Person1 中默认的无参构造函数对 Bean 进行实例化。

5、运行程序查看结果
使用 JUnit 测试运行 test() 方法
在这里插入图片描述
静态工厂方式实例化
1、创建实体类
在项目的 src 目录下创建一个名为 com.mengma.instance.static_factory 的包,并在该包下创建一个实体类 Person2,该类与 Person1 相同,不需要添加任何成员。
2、创建静态工厂类
在 com.mengma.instance.static_factory 包下创建一个名为 MyBeanFactory 的类,并在该类中创建一个名为 createBean() 的静态方法,用于创建 Bean 的实例,如下所示。

package com.mengma.instance.static_factory;
public class MyBeanFactory {
    // 创建Bean实例的静态工厂方法
    public static Person2 createBean() {
        return new Person2();
    }
}

3、创建spring配置文件

<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="person2" class="com.mengma.instance.static_factory.MyBeanFactory"
        factory-method="createBean" />
</beans>

注:上述代码中,定义了一个 id 为 person2 的 Bean,其中 class 属性指定了其对应的工厂实现类为 MyBeanFactory,而 factory-method 属性用于告诉 Spring 容器调用工厂类中的 createBean() 方法获取 Bean 的实例。

4、创建测试类

package com.mengma.instance.static_factory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest2 {
    @Test
    public void test() {
        // 定义Spring配置文件的路径
        String xmlPath = "com/mengma/instance/static_factory/applicationContext.xml"; // 初始化Spring容器,加载配置文件,并对bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 通过容器获取id为person2实例
        System.out.println(applicationContext.getBean("person2"));
    }
}

5、运行程序并查看结果
使用静态工厂的方式也成功对 Bean 进行了实例化。
在这里插入图片描述
实例工厂方式实例化
1、创建实体类
在项目的 src 目录下创建一个名为 com.mengma.instance.factory 的包,在该包下创建一个 Person3 类,该类与 Person1 类相同,不需要添加任何成员。
2、创建实例工厂类

package com.mengma.instance.factory;
public class MyBeanFactory {
    public MyBeanFactory() {
        System.out.println("person3工厂实例化中");
    }
    // 创建Bean的方法
    public Person3 createBean() {
        return new Person3();
    }
}

注:上述代码中,使用默认无参的构造方法输出 person3 工厂实例化中语句,使用 createBean 成员方法创建 Bean 的实例。

3、创建Spring配置文件

<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 配置实例工厂 -->
    <bean id="myBeanFactory" class="com.mengma.instance.factory.MyBeanFactory" />
    <!-- factory-bean属性指定一个实例工厂,factory-method属性确定使用工厂中的哪个方法 -->
    <bean id="person3" factory-bean="myBeanFactory" factory-method="createBean" />
</beans>

注:上述代码中,首先配置了一个实例工厂 Bean,然后配置了需要实例化的 Bean。在 id 为 person3 的 Bean 中,使用 factory-bean 属性指定一个实例工厂,该属性值就是实例工厂的 id 属性值。使用 factory-method 属性确定使用工厂中的 createBean() 方法。

4、创建测试类

package com.mengma.instance.factory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest3 {
    @Test
    public void test() {
        // 定义Spring配置文件的路径
        String xmlPath = "com/mengma/instance/factory/applicationContext.xml"; // 初始化Spring容器,加载配置文件,并对bean进行实例化
        // 初始化Spring容器,加载配置文件,并对bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 通过容器获取id为person3实例
        System.out.println(applicationContext.getBean("person3"));
    }
}

5、运行程序并查看结果
在这里插入图片描述

Spring中Bean的作用域

singleton

单例模式,使用 singleton 定义的 Bean 在 Spring 容器中只有一个实例,这也是 Bean 默认的作用域。
prototype

原型模式,每次通过 Spring 容器获取 prototype 定义的 Bean 时,容器都将创建一个新的 Bean 实例。
request

在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Request 内有效。
session

在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。
global Session

在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。

在上述五种作用域中,singleton 和 prototype 是最常用的两种
singleton 作用域
singleton 是 Spring 容器默认的作用域,当一个 Bean 的作用域为 singleton 时,Spring 容器中只会存在一个共享的 Bean 实例,并且所有对 Bean 的请求,只要 id 与该 Bean 定义相匹配,就只会返回 Bean 的同一个实例。

通常情况下,这种单例模式对于无会话状态的 Bean(如 DAO 层、Service 层)来说,是最理想的选择。

在 Spring 配置文件中,可以使用 元素的 scope 属性,将 Bean 的作用域定义成 singleton,其配置方式如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="singleton"/>

在项目的 src 目录下创建一个名为 com.mengma.scope 的包,在该包下创建 Person 类,类中不需要添加任何成员,然后创建 Spring 的配置文件 applicationContext.xml,将上述 Bean 的定义方式写入配置文件中,最后创建一个名为 PersonTest 的测试类,编辑后如下所示。

package com.mengma.scope;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PersonTest {
    @Test
    public void test() {
        // 定义Spring配置文件路径
        String xmlPath = "com/mengma/scope/applicationContext.xml";
        // 初始化Spring容器,加载配置文件,并对bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        // 输出获得实例
        System.out.println(applicationContext.getBean("person"));
        System.out.println(applicationContext.getBean("person"));
    }
}

使用 JUnit 测试运行 test() 方法,运行成功后
在这里插入图片描述
prototype 作用域

使用 prototype 作用域的 Bean 会在每次请求该 Bean 时都会创建一个新的 Bean 实例。因此对需要保持会话状态的 Bean(如 Struts2 的 Action 类)应该使用 prototype 作用域。

在 Spring 配置文件中,要将 Bean 定义为 prototype 作用域,只需将 元素的 scope 属性值定义成 prototype,其示例代码如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="prototype"/>

将《singleton作用域》部分中的配置文件更改成上述代码形式后,再次运行 test() 方法,输出结果中可以看到,两次输出的结果并不相同,这说明在 prototype 作用域下,Spring 容器创建了两个不同的 Person 实例。
在这里插入图片描述

Spring Bean的生命周期

Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
Bean 生命周期的整个执行过程描述如下。

  1. (1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。

(2)利用依赖注入完成 Bean 中所有属性值的配置注入。

(3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName()
方法传入当前 Bean 的 id 值。

(4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory()
方法传入当前工厂实例的引用。

(5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用
setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。

(6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法
postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP
就是利用它实现的。

(7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet()
方法。

(8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。

(9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法
postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。

(10)如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring
IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为
scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该
Bean。

(11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring
中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring
将调用该方法对 Bean 进行销毁。

Spring 为 Bean 提供了细致全面的生命周期过程,通过实现特定的接口或 <bean> 的属性设置,都可以对 Bean
的生命周期过程产生影响。虽然可以随意配置 <bean> 的属性,但是建议不要过多地使用 Bean 实现接口,因为这样会导致代码和
Spring 的聚合过于紧密。 < Spring Bean的作用域Spring基于XML装配Bean >

Spring 自动装配Bean

除了使用 XML 和 Annotation 的方式装配 Bean 以外,还有一种常用的装配方式——自动装配。自动装配就是指 Spring 容器可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。
通过案例实现自动装配:

<?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:p="http://www.springframework.org/schema/p" 
    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-2.5.xsd  
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="personDao" class="com.mengma.annotation.PersonDaoImpl" />
    <bean id="personService" class="com.mengma.annotation.PersonServiceImpl"
        autowire="byName" />
    <bean id="personAction" class="com.mengma.annotation.PersonAction"
        autowire="byName" />
</beans>

注:在上述配置文件中,用于配置 personService 和 personAction 的 元素中除了 id 和 class 属性以外,还增加了 autowire 属性,并将其属性值设置为 byName(按属性名称自动装配)。

默认情况下,配置文件中需要通过 ref 装配 Bean,但设置了 autowire=“byName”,Spring 会在配置文件中自动寻找与属性名字 personDao 相同的 ,找到后,通过调用 setPersonDao(PersonDao personDao)方法将 id 为 personDao 的 Bean 注入 id 为 personService 的 Bean 中,这时就不需要通过 ref 装配了。

Spring AOP概述

面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。

AOP 的全称是“Aspect Oriented Programming”,即面向切面编程,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。

AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。

目前最流行的 AOP 框架有两个,分别为 Spring AOP 和 AspectJ。

Spring JDK动态代理

JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的
JDK动态代理案例的使用:
1、创建项目及相关的jar包
2、创建接口CustomerDao

package com.mengma.dao;
public interface CustomerDao {
    public void add(); // 添加
    public void update(); // 修改
    public void delete(); // 删除
    public void find(); // 查询
}

3、创建实现类CustomerDaoImpl

package com.mengma.dao;
public class CustomerDaoImpl implements CustomerDao {
    @Override
    public void add() {
        System.out.println("添加客户...");
    }
    @Override
    public void update() {
        System.out.println("修改客户...");
    }
    @Override
    public void delete() {
        System.out.println("删除客户...");
    }
    @Override
    public void find() {
        System.out.println("修改客户...");
    }
}

4、创建切面类MyAspect

package com.mengma.jdk;
public class MyAspect {
    public void myBefore() {
        System.out.println("方法执行之前");
    }
    public void myAfter() {
        System.out.println("方法执行之后");
    }
}

注:上述代码中,在切面中定义了两个增强的方法,分别为 myBefore() 方法和 myAfter() 方法,用于对目标类(CustomerDaoImpl)进行增强

5、创建代理类MyBeanFactory

package com.mengma.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mengma.dao.CustomerDao;
import com.mengma.dao.CustomerDaoImpl;
public class MyBeanFactory {
    public static CustomerDao getBean() {
        // 准备目标类
        final CustomerDao customerDao = new CustomerDaoImpl();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 使用代理类,进行增强
        return (CustomerDao) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                new Class[] { CustomerDao.class }, new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        myAspect.myBefore(); // 前增强
                        Object obj = method.invoke(customerDao, args);
                        myAspect.myAfter(); // 后增强
                        return obj;
                    }
                });
    }
}

注:上述代码中,定义了一个静态的 getBean() 方法,这里模拟 Spring 框架的 IoC 思想,通过调用 getBean() 方法创建实例,第 14 行代码创建了 customerDao 实例。

第 16 行代码创建的切面类实例用于调用切面类中相应的方法;第 18~26 行就是使用代理类对创建的实例 customerDao 中的方法进行增强的代码,其中 Proxy 的 newProxyInstance() 方法的第一个参数是当前类的类加载器,第二参数是所创建实例的实现类的接口,第三个参数就是需要增强的方法。

在目标类方法执行的前后,分别执行切面类中的 myBefore() 方法和 myAfter() 方法。

6、创建测试类JDKProxyTest

package com.mengma.jdk;
import org.junit.Test;
import com.mengma.dao.CustomerDao;
public class JDKProxyTest {
    @Test
    public void test() {
        // 从工厂获得指定的内容(相当于spring获得,但此内容时代理对象)
        CustomerDao customerDao = MyBeanFactory.getBean();
        // 执行方法
        customerDao.add();
        customerDao.update();
        customerDao.delete();
        customerDao.find();
    }
}

注:上述代码中,在调用 getBean() 方法时,获取的是 CustomerDao 类的代理对象,然后调用了该对象中的方法

7、运行项目查看结果
使用 JUnit 测试运行 test() 方法,运行成功后,输出结果中可以看出,在调用目标类的方法前后,成功调用了增强的代码,由此说明,JDK 动态代理已经实现。
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot 是一个用于构建微服务的开源框架,它能够快速搭建项目并且提供了许多便捷的功能和特性。Spring Security 是一个用于处理认证和授权的框架,可以保护我们的应用程序免受恶意攻击。JWT(JSON Web Token)是一种用于身份验证的开放标准,可以被用于安全地传输信息。Spring MVC 是一个用于构建 Web 应用程序的框架,它能够处理 HTTP 请求和响应。MyBatis 是一个用于操作数据库的框架,可以简化数据库操作和提高效率。Redis 是一种高性能的键值存储系统,可以用于缓存与数据存储。 基于这些技术,可以搭建一个商城项目。Spring Boot 可以用于构建商城项目的后端服务,Spring Security 可以确保用户信息的安全性,JWT 可以用于用户的身份验证,Spring MVC 可以处理前端请求,MyBatis 可以操作数据库,Redis 可以用于缓存用户信息和商品信息。 商城项目的后端可以使用 Spring Boot 和 Spring Security 来搭建,通过 JWT 来处理用户的身份验证和授权。数据库操作可以使用 MyBatis 来简化与提高效率,同时可以利用 Redis 来缓存一些常用的数据和信息,提升系统的性能。前端请求则可以通过 Spring MVC 来处理,实现商城项目的整体功能。 综上所述,借助于 Spring Boot、Spring Security、JWT、Spring MVCMyBatis 和 Redis 这些技术,可以构建出一个高性能、安全可靠的商城项目,为用户提供良好的购物体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值