Spring基础配置

参考书籍《Spring Boot 实战》 汪云飞

一、Spring 框架四大原则

1、Spring 的所有功能的设计和实现都是基于这四大原则。

  • 使用POJO进行轻量级和最小侵入式开发。
  • 通过依赖注入和基本接口编程实现松耦合。
  • 通过AOP和默认习惯进行声明式编程。
  • 通过AOP和模板(template) 减少模式化代码

二、依赖注入

依赖注入:(deprndency injection-DI)是指容器负责创建对象和维护对象间的依赖关系,并非本身负责自己的创建和解决自己的依赖。主要目的是为了解耦,体现了一种组合的概念。
Spring IoC容器:(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到你需要的Bean中。Spring提供使用xml、注解、Java配置、groovy配置实现Bean

写一个简单的Hello world!

接下来我们简单实现一下

  • 配置类
package com.spring;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;

@Configurable
@ComponentScan("com.spring")
/**
 * Hello world!
 *
 */
public class Config 
{

}

在用@Configurable、@ComponentScan之前需要在pom.xml里面加入如下代码。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
  </parent>

<dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.9.RELEASE</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.1.9.RELEASE</version>
    </dependency>
  </dependencies>
  • 功能类Bean
package com.spring;

import org.springframework.stereotype.Service;

@Service//声明当前FunctionService类是Spring管理的一个Bean
public class FunctionService {
    public String sayHello(String word){
        return "Hello"+word+"!";
    }
}
  • 使用功能类Bean
package com.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service//声明该类是由Spring管理的一个Bean
public class UseFunctionService {
    @Autowired//注入
    FunctionService functionService;

    public String SayHello(String word){
        return functionService.sayHello(word);
    }
}

使用@Autowired注解。使得将FunctionService的实体Bean注入到UseFunctionService中,使得其具备FunctionService的功能

  • 运行
package com.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(Config.class);
        UseFunctionService useFunctionService=context.getBean(UseFunctionService.class);
        System.out.println(useFunctionService.SayHello(" world"));
        context.close();
    }
}

代码解释:

  • 使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数。
  • 注意:一定要在AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext()中加入配置类。否则会抛出如下异常。
Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@66a29884 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:950)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:974)
	at com.spring.Main.main(Main.java:8)

接下来运行,你就能看到自己想看到的结果啦~

Java配置

Java配置是通过@Configuration 和@Bean 来实现的。在这里也会与依赖注入相互比较。

实例
  • 功能类的Bean
package com.spring;
//这里没有Service注解
public class FunctionService {
    public String sayHello(String word){
        return "Hello"+word+"!";
    }
}

相比第一个方法,这里没有用到Sevice注解

  • 功能类的使用
package com.spring;


public class UseFunctionService {

    FunctionService functionService;

    public void setFunctionService(FunctionService functionService){
        this.functionService=functionService;
    }
    public String SayHello(String word){
        return functionService.sayHello(word);
    }
}

没有任何注解,并增加了一个set方法,在后面有用到。

  • 配置
package com.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {
    @Bean
    public FunctionService functionService(){
        return new FunctionService();
    }
    @Bean
    public UseFunctionService useFunctionService(){
        UseFunctionService useFunctionService=new UseFunctionService();
        useFunctionService.setFunctionService(functionService());
        return useFunctionService;
    }
}

在这里如果是用
@Configurable
@ComponentScan(“com.spring”)
也是完全没有问题的可以运行。那么@Configuration、@Bean是什么实现配置的。
@Configuration:声明当前是一个配置类,相当于一个Spring配置的xml文件。
@Bean:注解在方法上面,声明当前方法的返回值是一个Bean。

  • 运行
package com.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(Config.class);
        UseFunctionService useFunctionService=context.getBean(UseFunctionService.class);
        System.out.println(useFunctionService.SayHello(" world"));
        context.close();
    }

运行没有什么变化。

三、AOP

1、 什么是AOP

AOP:面向切面编程,相对于OOP面向对象编程,AOP的存在通常是为了解耦。
Spring 支持 AspectJ的注解式切面编程。

示例
  • 添加spring aop支持以及AspectJ依赖
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.8.5</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
  • 编写拦截规则的注释
package com.spring;

import java.lang.annotation.*;

//此注解只能修饰方法
@Target(ElementType.METHOD)
//当前注解如何去保持
@Retention(RetentionPolicy.RUNTIME)
//生成到API文档
@Documented
public @interface Action {
    String name();
}


注解本身没有功能,就和XML一样。

  • 编写使用注解的被拦截类
package com.spring;

import org.springframework.stereotype.Service;

@Service
public class DemoMethodService {
    public void add(){}
}

  • 编写使用方法规则被拦截类
package com.spring;

import org.springframework.stereotype.Service;

@Service
public class DemoMethodService {
    public void add(){}
}
  • 编写切面
package com.spring;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


@Aspect
@Component
public class LogAspect {

    //定义切面
    @Pointcut("@annotation(com.spring.Action)")
    public void annotationPointCut() {}

    //声明一个advice,并使用@pointCut定义的切点
    @After("annotationPointCut()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //从切面中获取当前方法
        Method method = signature.getMethod();
        //得到了方法,提取出他的注解
        Action action = method.getAnnotation(Action.class);
        //输出
        System.out.println("注解式拦截" + action.name());
    }
    //定义方法拦截的规则
    @Before("execution(* com.spring.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature =  (MethodSignature) joinPoint.getSignature();
        //拦截了方法
        Method method = signature.getMethod();
        //直接获取方法名字
        System.out.println("方法规则式拦截" + method.getName());
    }
}

注解解释
- @Aspect 注解声明这是一个切面。
- @Component 表示让此切面成为Spring容器管理的Bean。
- @PointCut注解声明切点。
- @After 注解声明一个建言,并使用PointCut定义切点。
- @Before 注解声明一个建言,此建言直接使用拦截器规则作为参数。

  • 配置类
package com.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

//JAVA配置类
@Configuration
//Bean扫描器
@ComponentScan("com.spring")
//开启spring对aspectJ的支持
@EnableAspectJAutoProxy
public class Config {
}

  • 运行
package com.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        DemoMethodService methodService = context.getBean(DemoMethodService.class);
        DemoAnnotationService annotationService = context.getBean(DemoAnnotationService.class);

        annotationService.add();
        methodService.add();

        context.close();
    }
}

注解解释
- @EnableAspectJAutoProxy 注解开启Spring对AspectJ代理的支持。

这次知识梳理就到此结束,欢迎大家留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值