Spring基础知识

1.spring的发展史。

第一阶段:xml配置

  在spring 1.x时代,使用spring开发满是xml配置的bean,随着项目的扩大。我们需要把xml配置文件分放到不同的配置文件里,那时候需要频繁的在开发的类和配置文件之间切换。

第二阶段:注解配置

  在spring 2.x时代,随着jdk1.5 带来的注解支持,spring提供了声明bean的注解(@Component 、 @Service),大大减少了配置量。这时圈子里存在着一种争论:注解配置和xml配置究竟哪个更好?我们最终选择应用的基本配置(如数据库配置)用xml,业务配置用注解。

第三阶段:java配置

  从spring 3.x到现在,spring提供了java配置的能力,使用java配置可以让你更理解你配置的bean,我们目前处于这个时代,spring 4.x和spring boot都推荐使用java配置。

2.Spring概述

  Spring框架主要提供了IOC容器、AOP、数据访问、web开发、消息、测试等相关技术的支持。每一个被spring管理的java对象都称之为Bean;而spring提供了一个IOC容器用来初始化对象,解决对象间的依赖管理和对象的使用。

(1).Spring的主要产品汇总:

Spring boot:使用默认开发配置来实现快速开发。

Sping XD: 用来简化大数据应用开发。

Sping cloud: 为分布式系统开发提供工具集。

Spring data:对主流的关系型和NoSql数据库的支持

Spring integration:通过消息机制对企业集成模式(EIP)的支持。

Spring batch:简化及优化大量数据的批处理操作。

Spring security:通过认证和授权保护应用。

Spring hateoas:基于HATEOAS原则简化rest服务开发。

Spring social:与社交网络Api(facebook、新浪微博)的集成。

Spring AMQP:对基于amqp的消息的支持。

Spring Mobile:提供对手机设备检测的功能,给不同的设备返回不同的页面的支持。

Spring for android:主要提供在android上消费restful api的功能。

Spring web flow:基于spring mvc提供基于向导流程式的web应用开发。

Spring web services:提供了基于协议有限的soap/web服务。

Spring ldap:简化使用ldap开发

Spring session:提供一个api及实现来管理用户会话信息。

(2).spring的jar应用。

  为解决传统jar包导入产生的问题,我们使用项目构建工具,目前主流的项目构建工具有,ant、 maven、gradle等。

  项目搭建时,我们使用传统的jar包导入方式(将项目所依赖第三方jar包复制到项目的类路径下,通常为lib目录),这种方式导入一个特定的jar包时,可能此jar包还依赖于其他的jar包,其他的jar包又依赖于更多的jar包,这也是我们平常遇到的ClassNotFound异常的主要原因。

(3).Maven相关知识

  Maven是基于项目对象模型的概念运作的,所以maven的项目都有一个pom.xml用来管理项目的依赖以及项目的编译等功能。

Dependencies元素:包含多个项目依赖需要使用的

Dependency元素:内部通过groupId 、artifactId及version确定唯一的依赖。

groupId:组织的唯一标识。

artifactId: 项目的唯一标识。

Version: 项目版本。

变量定义

<!-- 定义变量 -->
      <properties>
          <spring-context.version>5.1.5.RELEASE</spring-context.version>
 </properties>
       <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <!-- 使用变量 -->
          <version>${spring-context.version}</version>
       </dependency>

Maven 编译项目插件 maven-compiler-plugin

参考

<build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
      <!-- maven-compiler-plugin插件是一个Maven插件,用来编译项目代码 -->
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
              <configuration>
                  <!-- 默认源 jdk1.7 -->
                  <source>1.7</source>
                  <!-- 默认目标 jdk1.7 -->
                  <target>1.7</target>
              </configuration>
          </plugin>
      </plugins>
</build>

(4).Maven项目搭建

建好maven项目后,修改pom.xml.增加spring依赖,添加编译插件,将编译级别设置为1.7。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.cw.study</groupId>
  <artifactId>Spring-MavenTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
 <!-- 定义变量 -->
 <properties>
       <java.version>1.7</java.version>
   </properties>
<!-- jar包依赖 -->
   <dependencies>
       <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.1.5.RELEASE</version>
       </dependency>
   </dependencies>
    <!-- 插件配置 -->
   <build>
       <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
   <!-- maven-compiler-plugin插件是一个Maven插件,用来编译项目代码 -->
<artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
              <configuration>
                 <!-- 使用变量 -->
                  <!-- 源目标 -->
                  <source>${java.version}</source>
                  <!-- 默认目标 -->
                  <target>${java.version}</target>
              </configuration>
          </plugin>
       </plugins>
   </build>
</project>

设置好相关jar包和配置后 ,使用 右键 –> Maven –> Update Project.

3.Spring基础配置

(1).Spring框架本身有四大原则:

1).使用pojo进行轻量级和最小侵入式开发。

2).通过依赖注入和基于接口编程实现松耦合。

3).通过AOP和默认习惯进行声明式编程。

4).使用aop和模板减少模式化代码。

(2).依赖注入:

1.控制反转和依赖注入在spring环境下是等同的概念。

2.控制反转是通过依赖注入实现的,依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。

依赖注入目的:为了解耦。

Spring IOC容器负责创建bean,并通过容器将功能类bean注入到你需要的bean中,spring提供使用xml、注解、java配置、groovy配置实现bean的创建和注入。

声明bean 的注解:

@Component组件:没有明确的角色。

@Service组件:在业务逻辑层(service)使用。

@Repository组件:在数据库访问层(dao层)使用。

@Controller组件:在展现层(mvc –> spring mvc)使用。

注入bean的注解

@Autowired : spring 提供的注解。

@Inject : jsr-330提供的注解。

@Resource : jsr-250提供的注解。

上述三个可以注解在set方法上或者属性上。使得代码更少、层次更清晰。

@Configuration声明当前类是一个配置类。

@ComponentScan,自动扫描包名下所有使用 【@Service、@Component、 @repository和@Controller】类,并注册为bean。

(3).Java配置

  Java配置是spring4.x推荐的配置方式,可以完全替代xml配置,java配置也是spring boot 推荐的配置方式。

  Java配置是通过@Configuration和@bean来实现的。

@Configuration声明当前类是一个配置类,相当于spring配置的xml文件。

@Bean注解在方法上,声明当前方法的返回值为一个bean.

配置原则:

全局配置使用java配置:数据库相关配置,mvc相关配置。

业务bean使用注解配置:如@service、@Component、@Repository、@Controller

①使用java配置处理业务案例(一般不建议)

public class FuncitonService {
    public String sayHello(String name){
        return name+"say hello";
    }
}
public class UseFunctionService {
    private FuncitonService funcitonService;

    public void setFuncitonService(FuncitonService funcitonService) {
        this.funcitonService = funcitonService;
    }
    public String sayHello(String name){
        return funcitonService.sayHello(name);
    }
}
@Configuration
public class JavaConfig {
    @Bean
    public FuncitonService getFunctionService(){
        return new FuncitonService();
    }
    @Bean
    public UseFunctionService getUseFuncitonService(FuncitonService funcitonService){
        UseFunctionService service = new UseFunctionService();
        service.setFuncitonService(funcitonService);
        return service;
    }    
}
public class MainFunction {
    public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
        UseFunctionService bean = context.getBean(UseFunctionService.class);
        System.out.println(bean.sayHello("hhh"));
    }
}

②使用注解配置处理业务配置案例

@Repository
public class FuncitonService {
    public String sayHello(String name){
        return name+"say hello";
    }
}
@Service
public class UseFunctionService {
    @Autowired
    private FuncitonService funcitonService;
    public void setFuncitonService(FuncitonService funcitonService) {
        this.funcitonService = funcitonService;
    }
    public String sayHello(String name){
        return funcitonService.sayHello(name);
    }
}

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

    <context:component-scan base-package="cn.cw.study"/>     
</beans> 

public class MainFunction {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        System.out.println(context);
        UseFunctionService bean = (UseFunctionService) context.getBean("useFunctionService");
        System.out.println(bean.sayHello("test"));
    }
}

(4).Aop

Aop:面向切面编程,相对于oop面向对象编程。

Spring的AOP的存在目的是为了解耦。

Aop可以让一组类共享相同的行为。在OOP只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,Aop弥补了OOP的不足。

Spring支持AspectJ的注解式切面编程

①.使用@Aspect声明是一个切面。

②.使用@After、@Before、@Around定义建言,可直接将拦截规则(切点)作为参数。

③.其中@After、@Before、@Around参数的拦截规则为切点,为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。

④.其中符合条件的每一个拦截处为连接点(JoinPoint)

拦截方式有两种:基于注解拦截 和 基于方法规则拦截。

注解式拦截能够更好的控制要拦截的粒度和获得更丰富的信息,spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)上面都使用此中形式的拦截。

原理

当多个方法调用一个method时,我们只要定义该方法,无须在多个方法显示调用它,系统会“自动”执行该特殊方法。Aop专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题。在javaEE应用中,常常通过aop来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。

Java元注解

代码示例:

(1)添加spring aop 支持及AspectJ依赖

<!-- 添加spring aop支持及AspectJ依赖 -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.1.5.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.8.9</version>
  </dependency>
  <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.9</version>
  </dependency>

(2)编写拦截规则的注解。

//编写拦截规则注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
    String name();
}

(3)编写使用注解的被拦截类。

//编写使用注解的被拦截类
@Service
public class DemoAnnotationService {
    @Action(name = "注解式拦截的add操作")
    public void add(){}
}

(4)编写使用方法规则的被拦截类。

//编写使用方法规则的被拦截类
@Service
public class DemoMethodService {
    public void add(){}
}

(5)编写切面。

@Aspect   //声明一个切面
@Component  //让此切面成为spring容器管理的bean
public class LogAspect {
    @Pointcut("@annotation(cn.cw.study.aop.Action)")//声明切点
    public void annotationPointCut(){};
    @After("annotationPointCut()")
    public void after(JoinPoint point){
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        Action annotation = method.getAnnotation(Action.class);
        System.out.println("注解式拦截"+annotation.name());
    }
    @Before("execution(* cn.cw.study.aop.DemoMethodService.*(..))")
    public void before(JoinPoint point){
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        System.out.println("方法规则式拦截"+method.getName());
    }
}

(6)配置类。

@Configuration
@ComponentScan("cn.cw.study.aop")
@EnableAspectJAutoProxy //开启spring对AspectJ支持
public class AopConfig {

}

(7)运行main方法。

public static void main(String[] args) {
AnnotationConfigApplicationContext context = 
new AnnotationConfigApplicationContext(AopConfig.class);
    DemoAnnotationService demoAnnotation = 
context.getBean(DemoAnnotationService.class);
    DemoMethodService demoMethod = 
context.getBean(DemoMethodService.class);
        demoAnnotation.add();
        demoMethod.add();
        context.close();
    }

文章标题:Spring基础知识

发布时间:2019-11-14, 16:19:44

最后更新:2019-11-14, 16:19:45