Spring基础(3)--- Spring基础配置

Spring 基础配置

Sprin框架本身有四大原则:

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

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

1、依赖注入

1.1、理论

我们经常说的控制反转(IOC)和依赖注入(DI)在Spring环境下是两个等同的概念,控制反转是通过依赖注入实现的。所谓依赖注入是指容器在负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。

依赖注入的主要目的是为了解耦,体现了一种“组合”的理念。如果你希望你的类具备一个类的功能如果继承一个父类,子类和父类将耦合,如果组合另外一个类则使耦合度降低。

Spring IOC容器负责创建Bean,并将功能类的Bean注入到你需要的Bean中,Spring可以通过XML配置,注解还有JAVA配置来实现Bean的创建和出入,无能是那种配置,这些配置都被称之为配置元数据,也叫描述数据,意思就是这个数据本身不具备任何执行能力,只能通过外界代码来对这些元数据进行解析后进行一些有意思的数据。

声明Bean的注解:
  • @Component 组件,没有明确的角色。
  • @Controller 在展现层(MVC→SpringMVC)使用。
  • @Service 在业务逻辑层(service层)使用。
  • @Repository 在数据访问层(dao层)使用。
    注入Bean的注解,一般情况下通用
  • @Autowired:Spring提供的注解。
  • @Inject:JSR-330提供的注解。
  • @Resource:JSR-250提供的注解。

1.2、示例

1)编写功能类的Bean。

package com.wisely.highlight_spring4.ch1.di;

import org.springframework.stereotype.Service;

@Service //使用@Service注解声明当前FunctionService类是Spring管理的一个Bean。其中,使用@Controller、@Service、@Repository和@Controller是等效的,可根据当前Bean在哪一层使用。
public class FunctionService {
    public String sayHello(String word){
        return "Hello " + word +" !";
    }

}

2)使用功能类的Bean。


package com.wisely.highlight_spring4.ch1.di;

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

@Service //声明当前类是Spring管理的一个Bean
public class UseFunctionService {
    @Autowired //将FunctionService的实体Bean注入到UseFunctionService中
    FunctionService functionService;

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

}

3)配置类

package com.wisely.highlight_spring4.ch1.di;

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

@Configuration //声明当前类是一个配置类
@ComponentScan("com.wisely.highlight_spring4.ch1.di") //自动扫描包名下所有的@Service、@Component、@Repository、@Controller的类并注册为Bean
public class DiConfig {

}

4)运行

package com.wisely.highlight_spring4.ch1.di;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        //使用AnnotationConfigApplicationContext作为容器,接受一个配置类作为参数拿到上下文对象
         AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(DiConfig.class);
         //获得Bean
         UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);

         System.out.println(useFunctionService.SayHello("world"));//Hello world !

         context.close();
    }
}

2、Java配置

2.1、理论

Java配置是Spring4.x推荐的配置方式,可以完全取代xml配置;Java配置也是SpringBoot推荐的配置方式。

Java配置主要是通过@Configuration和@Bean来实现的。

  • @Configuration声明当前类是一个配置类,相当于一个Spring里面配置的xml文件。
  • @Bean注解在方法上,声明当前方法的返回值是一个Bean。

    如果用Java配置替代xml配置的话,那我们主要的原则是:全局配置用Java配置(如数据库相关配置、MVC相关配置),业务Bean的配置使用的是注解配置(@Service、@Component、@Repository、@Controller).

2.2、示例

1)编写功能类的Bean

package com.wisely.highlight_spring4.ch1.javaconfig;
//这里没有用@Service注解声明Bean
public class FunctionService {

    public String sayHello(String word){
        return "Hello " + word +" !";
    }

}

2)使用功能类的Bean

package com.wisely.highlight_spring4.ch1.javaconfig;

//此处没有用@Service声明Bean
public class UseFunctionService {
    //此处也没有用@AutoWired注解注入
    FunctionService functionService;

    public void setFunctionService(FunctionService functionService) {
        this.functionService = functionService;
    }

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

}

3)配置类

package com.wisely.highlight_spring4.ch1.javaconfig;

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

@Configuration //声明这是一个配置类,这意味着这个类里面有0个或者多个@Bean注解,此处没有用@ComponentScan包扫描注解
public class JavaConfig {
    @Bean //声明当前方法返回的是一个Bean,Bean的名称是方法名
    public FunctionService functionService(){
        return new FunctionService();
    }

    @Bean
    public UseFunctionService useFunctionService(){
        UseFunctionService useFunctionService = new UseFunctionService();
        useFunctionService.setFunctionService(functionService()); //注入FunctionService的Bean时候直接调用functionService()。
        return useFunctionService;

    }

//  @Bean
    //另外一种注入方式:直接将FunctionService作为参数给useFunctionService(),这也是Spring容器中,只要容器中存在这个Bean,就可以在
    //另外一个Bean的声明方法中作为参数注入。
//  public UseFunctionService useFunctionService(FunctionService functionService){//4
//      UseFunctionService useFunctionService = new UseFunctionService();
//      useFunctionService.setFunctionService(functionService);
//      return useFunctionService;
//  }
}

4)运行

package com.wisely.highlight_spring4.ch1.javaconfig;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
         AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(JavaConfig.class); 

         UseFunctionService useFunctionService = context.getBean(UseFunctionService.class); 

         System.out.println(useFunctionService.SayHello("java config"));//Hello java config!

         context.close();

    }
}

3、AOP

3.1、理论

AOP:面向切面编程,相对于OOP面向对象编程。

Spring的AOP的存在主要是为了解耦。AOP可以让一组类共享共同的行为,在OOP中只能用集成类或者实现接口来实现,这样会是代码的耦合性增强,并且集成只能单继承,阻碍更多的行为添加在一组类上,AOP主要是为了弥补OOP的不足。

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

  1. 使用@Asopect声明一个切面。
  2. 使用@After、@Before、@Around定义建言(advice),可以直接将拦截规则(切点)作为参数。
  3. 其中@After、@Before、@Around参数的拦截规则为切点(PonintCut),为了使切点复用,可以用@PonitCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。

    4.其中符合条件的每一个被拦截处被称为连接点(JoinPonit)。

3.2、示例

1)pom.xml中添加spring aop支持以及AspectJ依赖

       <!-- spring aop支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <!-- aspectj支持 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.6</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>

2)编写拦截规则注解(自定义一个注解)

package com.wisely.highlight_spring4.ch1.aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
//  作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
//          取值(ElementType)有:
//            1.CONSTRUCTOR:用于描述构造器
//            2.FIELD:用于描述域
//            3.LOCAL_VARIABLE:用于描述局部变量
//            4.METHOD:用于描述方法
//            5.PACKAGE:用于描述包
//            6.PARAMETER:用于描述参数
//            7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
//@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
//  作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
//  取值(RetentionPoicy)有:
//    1.SOURCE:在源文件中有效(即源文件保留)
//    2.CLASS:在class文件中有效(即class保留)
//    3.RUNTIME:在运行时有效(即运行时保留)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
    String name();
}

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

package com.wisely.highlight_spring4.ch1.aop;

import org.springframework.stereotype.Service;

@Service
public class DemoAnnotationService {
    @Action(name="注解式拦截的add操作")
    public void add(){} 

}

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


package com.wisely.highlight_spring4.ch1.aop;

import org.springframework.stereotype.Service;

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

5)编写切面

package com.wisely.highlight_spring4.ch1.aop;

import java.lang.reflect.Method;

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;

@Aspect //声明一个切面
@Component //让此切面成为Spring容器管理的Bean
public class LogAspect {

    @Pointcut("@annotation(com.wisely.highlight_spring4.ch1.aop.Action)") //声明切点
    public void annotationPointCut(){};

      @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.wisely.highlight_spring4.ch1.aop.DemoMethodService.*(..))") //前置通知
        public void before(JoinPoint joinPoint){
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            System.out.println("方法规则式拦截,"+method.getName());
        }
}

6)配置类

package com.wisely.highlight_spring4.ch1.aop;

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

@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch1.aop")
@EnableAspectJAutoProxy //开启Spring对AspectJ支持
public class AopConfig {

}

7)运行

package com.wisely.highlight_spring4.ch1.aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
         AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(AopConfig.class);

         DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);

         DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);

         demoAnnotationService.add();

         demoMethodService.add();

         context.close();
    }

}

原文地址:https://www.cnblogs.com/bigfly277/p/9469990.html

时间: 2024-10-24 00:46:52

Spring基础(3)--- Spring基础配置的相关文章

spring学习——Ioc基础三(Ioc配置使用)

一.XML配置的结构  一般配置文件结构如下: <beans>       <import resource="resource1.xml"/>       <bean id="bean1"class=""></bean>       <bean id="bean2"class=""></bean>   <bean name=&q

Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解

前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式(RestTemplate.WebClient.Feign)> <Spring Cloud Alibaba基础教程:使用Nacos作为配置中心> 上一篇,我们学习了如何在Nacos中创建配置,以及如何使用Spring Cloud Alibaba的Nacos客户端模块来加载配置.在入门例子中,我们只配

Spring Cloud Alibaba基础教程:Nacos配置的多文件加载与共享配置

前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> <Spring Cloud Alibaba基础教程:使用Nacos作为配置中心> <Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解> <Spring Cloud Alibaba基础教程:Nacos配置的多环境管理> 对于Nacos作为配置中

Spring温习(1)--最基础的示例

Spring温习(1)--最基础的示例 博客分类: 框架-Spring专栏 SpringXMLBeanWebDAO 从现在开始,我将从Spring为起点,逐步复习几大框架各方面的知识,以便今后查看使用 第一各Spring示例 必须包:spring-framework-2.5.6\dist\spring.jar spring-framework-2.5.6\lib\jakarta-commons\common-logging.jar 为了方便测试还需要:spring-framework-2.5.6

Spring框架的一些基础知识

Spring 框架 Spring 框架是一个分层架构,由 7 个定义良好的模块组成.Spring 模块构建在核心容器之上,核心容器定义了创建.配置和管理 bean 的方式,如图 1 所示. 图 1. Spring 框架的 7 个模块 组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现.每个模块的功能如下: 核心容器:核心容器提供 Spring 框架的基本功能.核心容器的主要组件是 BeanFactory,它是工厂模式的实现.BeanFactory 使用控

Spring源码阅读:Spring事务管理的基础

上一节了解了全局事务与局部事务以及Spring提供的两种事务模式:编程式事务与声明式事务. 不论是编程式的事务处理,还是声明式的事务处理.他们都要对局部事务和全局事务以支持,也就是说要对JDBC进行支持.ORM框架,同时也要对JTA进行支持.他们的公共部分是commit,rollback.通过这一节的了解,我相信以后配置Spring事务时,就不需要在去网上查资料了或者去查Spring的参考文档了. 因此,Spring设计了如下的事务管理框架: 从上面的类图中和容易可以看出分为三部分:Platfo

【夯实基础】Spring在ssh中的作用

尊重版权:http://blog.csdn.net/qjlsharp/archive/2009/03/21/4013255.aspx 写的真不错. 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句.Struts是用来做应用层的,他它负责调用业务逻辑serivce层.所以SSH框架的流程大致是:Jsp页面----Struts------Service(业务逻辑处理类)

事务基础知识--&gt;Spring事务管理

Spring虽然提供了灵活方便的事务管理功能,但这些功能都是基于底层数据库本身的事务处理机制工作的.要深入了解Spring的事务管理和配置,有必要先对数据库事务的基础知识进行学习. 何为数据库事务 “一荣俱荣,一损俱损”这句话很能体现事务的思想,很多复杂的事物要分步进行,但它们组成一个整体,要么整体生效,要么整体失效.这种思想反映到数据库上,就是多个SQL语句,要么所有执行成功,要么所有执行失败. 数据库事务有严格的定义,它必须同时满足 4 个特性:原子性(Atomic).一致性(Consist

零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)

作者各必备工具的版本如下: Tomcat:apache-tomcat-7.0.63 (下载链接) Java EE - Eclipse:Luna Service Release 1 v4.4.1 (下载链接) Spring:4.2.0.RELEASE (无须下载) JDK:1.7.0_67 (下载链接) 步骤 1 使用 Java EE - Eclipse 新建一 Dynamic Web Project. 步骤 2 输入项目名 bdp.Target Runtime 选 Apache Tomcat 7

spring batch(一):基础部分

spring batch(一):基础部分 博客分类: Spring java spring batch 官网: http://www.springsource.org/spring-batch 下载页面: http://static.springsource.org/spring-batch/downloads.html 文档: http://static.springsource.org/spring-batch/reference/index.html 数据库表格创建连接:DDL http: