1. Spring基础配置

Spring框架本身有四大原则:

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

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

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

4) 使用AOP和模板(template)减少模式化代码

所谓依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。依赖注入主要目的是为了解耦。

Spring Ioc容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到你需要的Bean中。

声明Bean的注解:

a. @Component组件

b. @Service在业务逻辑层(Service层)使用

c. @Repository在数据访问层(dao层)使用

e. @Controller在展现层使用

注入Bean的注解,一般情况下是通用的:

a. @Autowired:Spring提供的注解

b. @Resourse: JSR-250提供的注解

c. @Inject: JSR-330提供的注解

示例:

1) 构件maven项目,其pom.xml配置文件如下:

 <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>com.ws</groupId>
<artifactId>study1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>study1</name>
<url>http://maven.apache.org</url> <properties>
<java.version>1.7</java.version>
<spring-framework.version>4.1.5.RELEASE</spring-framework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
</dependencies>
</project>

2) 编写功能类Bean

 package com.ws.study.one;

 import org.springframework.stereotype.Service;

 // @Service注解声明当前FunctionService类是Spring管理的一个Bean
@Service
public class FunctionService {
public String sayHello(String word){
return "Hello " + word + " !";
}
}

3) 使用编写好的功能类Bean

 package com.ws.study.one;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; // @Service注解声明当前类是Spring管理的一个Bean
@Service
public class UseFunctionService { // @Autowired实体将FunctionService的实体Bean注入到UseFunctionService中,
// 进而使UseFunctionService具备FunctionService的功能
@Autowired
FunctionService functionService; public String sayHello(String word){
return functionService.sayHello(word);
}
}

4) 配置类

 package com.ws.study.one;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; // @Component声明当前类是一个配置类
@Component
// 使用@ComponentScan,自动扫描包下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
@ComponentScan("com.ws.study.one")
public class DiConfig { }

5) 运行类

 package com.ws.study.one;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 public class Main {
public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class); // 获取声明配置的UseFunctionService的Bean
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class); System.out.println(useFunctionService.sayHello("di")); context.close();
}
}

6) 运行结果

 五月 29, 2018 11:07:20 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:07:20 CST 2018]; root of context hierarchy
Hello di !
五月 29, 2018 11:07:20 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:07:20 CST 2018]; root of context hierarchy

2. Java配置

java配置可以完全替代xml配置,也是Spring Boot推荐的配置方式。java配置是通过@Configuration和@Bean来实现的。

a. @Configuration声明当前类是一个配置类,相当于一个Spring配置的xml文件

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

何时使用java配置或注解配置?原则:全局配置使用java配置(如数据库配置、MVC相关配置),业务Bean的配置使用注解配置(@Service、@Component、@Repository、@Controller)

示例:

1) 编写功能类

 package com.ws.study.javaconfig;

 // 此处没有@Service声明的Bean
public class FunctionService {
public String sayHello(String word){
return "Hello " + word + " !";
}
}

2) 使用功能类

 package com.ws.study.javaconfig;

 //此处没有@Service声明的Bean
public class UseFunctionService {
// 此处没有@Autowired声明的Bean
FunctionService functionService; public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
} public String sayHello(String word){
return functionService.sayHello(word);
}
}

3) 配置类

 package com.ws.study.javaconfig;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; // 使用@Configuration注解声明当前类是一个配置类。意味着这个类中可能存在0个或多个@Bean注解
// 此处没有使用包扫描,是因为所有的Bean都在此类中定义了
@Configuration
public class JavaConfig { // 使用@Bean注解声明当前方法FunctionService的返回值是一个Bean,Bean的名称是方法名
@Bean
public FunctionService functionService(){
return new FunctionService();
} @Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
// 注入FunctionService的Bean时候直接调用functionService()
useFunctionService.setFunctionService(functionService());
return useFunctionService;
} // // 另外一种注解方式,直接将FunctionService作为参数给useFunctionService()
// // 在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中写入
// @Bean
// public UseFunctionService useFunctionService(FunctionService functionService){
// UseFunctionService useFunctionService = new UseFunctionService();
// useFunctionService.setFunctionService(functionService);
// return useFunctionService;
// }
}

4) 运行类

 package com.ws.study.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")); context.close();
}
}

5) 运行结果

 五月 29, 2018 11:36:47 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:36:47 CST 2018]; root of context hierarchy
Hello java config !
五月 29, 2018 11:36:47 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:36:47 CST 2018]; root of context hierarchy

3. AOP

AOP为面向切面编程,切面编程是指在程序运行期间将某段代码,动态的切入到某个类的指定方法的指定位置。AOP存在的目的是为了解耦。AOP可以让一组类共享相同的行为。Spring支持AspectJ的注解式切面编程。

a. 使用@AspectJ声明是一个切面

b. 使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。为了使拦截规则(切点)复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。

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

Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)上面都使用注解式拦截。

示例:

1) 添加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.ws.study.aop;

 import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; // 注解本身没有功能
// 注解和XML都是元数据
// 注解的功能来自用这个注解的地方
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
}

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

 package com.ws.study.aop;

 import org.springframework.stereotype.Service;

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

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

 package com.ws.study.aop;

 import org.springframework.stereotype.Service;

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

5) 编写切面

 package com.ws.study.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注解声明一个切面
@Aspect
// @Component让此切面成为Spring容器管理的Bean
@Component
public class LogAspect { // @Pointcut注解声明切点
@Pointcut("@annotation(com.ws.study.aop.Action)")
public void annotationPointCut(){}; // 通过@After注解声明一个建言,并使用@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注解声明一个建言,此建言直接使用拦截规则作为参数
@Before("execution(* com.ws.study.aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截: "+method.getName());
}
}

6) 配置类

 package com.ws.study.aop;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("com.ws.study.aop")
// 使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持
@EnableAspectJAutoProxy
public class AopConfig { }

7) 运行类

 package com.ws.study.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);
demoAnnotationService.add(); DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoMethodService.add(); context.close();
} }

8) 运行结果

 五月 30, 2018 10:06:14 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy
注解式拦截:注解式拦截的add操作
方法规则式拦截: add
五月 30, 2018 10:12:09 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy

Spring Boot实战(1) Spring基础的更多相关文章

  1. Spring Boot实战(3) Spring高级话题

    1. Spring Aware Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的.即你可以将你的容器替换成别的容器. 实际项目中,不可避免地会用到Spring容 ...

  2. Spring Boot实战(2) Spring常用配置

    1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...

  3. Spring Boot实战

    Spring在java EE开发中是实际意义上的标准,但我们在开发Spring的时候可能会遇到以下令人头疼的问题: 1.大量配置文件的定义.2.与第三方软件整合的技术问题. Spring每个版本的退出 ...

  4. 《spring boot 实战》读书笔记

    前言:虽然已经用spring boot开发过一套系统,但是之前都是拿来主义,没有系统的,全面的了解过这套框架.现在通过学习<spring boot实战>这本书,希望温故知新.顺便实现自己的 ...

  5. Spring Boot实战系列-----------邮件发送

    快速导航 添加Maven依赖 配置文件增加邮箱相关配置 Service.Test项目代码构建 五种邮件发送类型讲解 文本邮件 html邮件 附件邮件 html内嵌图片邮件 模板邮件 问题汇总 添加ma ...

  6. 《Spring Boot实战》笔记(目录)

    目录 目 录第一部分 点睛Spring 4.x第1 章 Spring 基础 .............................................................. ...

  7. spring boot 实战教程

    二八法则 - get more with less Java.spring经过多年的发展,各种技术纷繁芜杂,初学者往往不知道该从何下手.其实开发技术的世界也符合二八法则,80%的场景中只有20%的技术 ...

  8. 《Spring Boot 实战纪实》之需求管理

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

  9. 《Spring Boot 实战纪实》之前言

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

随机推荐

  1. File类和Directory类

    File类和Directory类分别用来对文件和各种目录进行操作,这两类可以被实例化,但不能被其他类集成. 1. File类(静态类) File类支持对文件的基本操作,它包括用于创建.复制.删除.移动 ...

  2. 运维利器:钉钉机器人脚本告警(Linux Shell 篇)

    写在前面的话 目前换了几家公司,且最近几家都是以钉钉作为公司 OA 聊天工具,总的来说还是很不错的.最近去了新公司,由于公司以前没有运维,所以监控,做自动化等方面都没有实施,恰逢这个机会把最近做的关于 ...

  3. [SinGuLaRiTy] 动态规划题目复习

    [SinGuLaRiTy-1026] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. [UVA 1025] A Spy in the Metr ...

  4. Java-BubbleSort

    前言 我们都知道BubbleSort这种排序算法不管从大到小排序,还是从小到大排序,都是相邻的两个进行比较,然后不符合条件时交换顺序.下面来看看引用类型是怎么进行BubbleSort的. 内容 需求: ...

  5. 使用pycharm创建自己的第一个django项目

    PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制. ...

  6. UICollectionView Layout自定义 Layout布局

    from:   http://www.tuicool.com/articles/vuyIriN 当我们使用系统自带的UICollectionViewFlowLayout无法实现我们的布局时,我们就可以 ...

  7. 2.mybatis 的列名与数据库字段不对应

    mybatis 的列名与数据库字段不对应 1.别名 映射文件 : BlogMapper.xml <mapper namespace="com.xms.mybatis.mapper.Bl ...

  8. VS2008 生成的程序有管理员权限

    vs 2008 . 解决方案---右键属性----连接器---清单文件---UAC执行级别---设置为requireAdministrator

  9. clojure with postgres

    主要关注访问pg.不关心其他db 1 clojure.java.jdbc https://github.com/clojure/java.jdbc http://clojure-doc.org/art ...

  10. hdu1430 魔板(康拓展开 bfs预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...