Spring Boot实战(1) Spring基础
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基础的更多相关文章
- Spring Boot实战(3) Spring高级话题
1. Spring Aware Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的.即你可以将你的容器替换成别的容器. 实际项目中,不可避免地会用到Spring容 ...
- Spring Boot实战(2) Spring常用配置
1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...
- Spring Boot实战
Spring在java EE开发中是实际意义上的标准,但我们在开发Spring的时候可能会遇到以下令人头疼的问题: 1.大量配置文件的定义.2.与第三方软件整合的技术问题. Spring每个版本的退出 ...
- 《spring boot 实战》读书笔记
前言:虽然已经用spring boot开发过一套系统,但是之前都是拿来主义,没有系统的,全面的了解过这套框架.现在通过学习<spring boot实战>这本书,希望温故知新.顺便实现自己的 ...
- Spring Boot实战系列-----------邮件发送
快速导航 添加Maven依赖 配置文件增加邮箱相关配置 Service.Test项目代码构建 五种邮件发送类型讲解 文本邮件 html邮件 附件邮件 html内嵌图片邮件 模板邮件 问题汇总 添加ma ...
- 《Spring Boot实战》笔记(目录)
目录 目 录第一部分 点睛Spring 4.x第1 章 Spring 基础 .............................................................. ...
- spring boot 实战教程
二八法则 - get more with less Java.spring经过多年的发展,各种技术纷繁芜杂,初学者往往不知道该从何下手.其实开发技术的世界也符合二八法则,80%的场景中只有20%的技术 ...
- 《Spring Boot 实战纪实》之需求管理
目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...
- 《Spring Boot 实战纪实》之前言
目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...
随机推荐
- File类和Directory类
File类和Directory类分别用来对文件和各种目录进行操作,这两类可以被实例化,但不能被其他类集成. 1. File类(静态类) File类支持对文件的基本操作,它包括用于创建.复制.删除.移动 ...
- 运维利器:钉钉机器人脚本告警(Linux Shell 篇)
写在前面的话 目前换了几家公司,且最近几家都是以钉钉作为公司 OA 聊天工具,总的来说还是很不错的.最近去了新公司,由于公司以前没有运维,所以监控,做自动化等方面都没有实施,恰逢这个机会把最近做的关于 ...
- [SinGuLaRiTy] 动态规划题目复习
[SinGuLaRiTy-1026] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. [UVA 1025] A Spy in the Metr ...
- Java-BubbleSort
前言 我们都知道BubbleSort这种排序算法不管从大到小排序,还是从小到大排序,都是相邻的两个进行比较,然后不符合条件时交换顺序.下面来看看引用类型是怎么进行BubbleSort的. 内容 需求: ...
- 使用pycharm创建自己的第一个django项目
PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制. ...
- UICollectionView Layout自定义 Layout布局
from: http://www.tuicool.com/articles/vuyIriN 当我们使用系统自带的UICollectionViewFlowLayout无法实现我们的布局时,我们就可以 ...
- 2.mybatis 的列名与数据库字段不对应
mybatis 的列名与数据库字段不对应 1.别名 映射文件 : BlogMapper.xml <mapper namespace="com.xms.mybatis.mapper.Bl ...
- VS2008 生成的程序有管理员权限
vs 2008 . 解决方案---右键属性----连接器---清单文件---UAC执行级别---设置为requireAdministrator
- clojure with postgres
主要关注访问pg.不关心其他db 1 clojure.java.jdbc https://github.com/clojure/java.jdbc http://clojure-doc.org/art ...
- hdu1430 魔板(康拓展开 bfs预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...