• 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配置文件如下:

      1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      2 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      3 	<modelVersion>4.0.0</modelVersion>
      4 
      5 	<groupId>com.ws</groupId>
      6 	<artifactId>study1</artifactId>
      7 	<version>0.0.1-SNAPSHOT</version>
      8 	<packaging>jar</packaging>
      9 
     10 	<name>study1</name>
     11 	<url>http://maven.apache.org</url>
     12 
     13 	<properties>
     14 		<java.version>1.7</java.version>
     15 		<spring-framework.version>4.1.5.RELEASE</spring-framework.version>
     16 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     17 	</properties>
     18 
     19 
     20 	<dependencies>
     21 		<dependency>
     22 			<groupId>junit</groupId>
     23 			<artifactId>junit</artifactId>
     24 			<version>3.8.1</version>
     25 			<scope>test</scope>
     26 		</dependency>
     27 		<dependency>
     28 			<groupId>org.springframework</groupId>
     29 			<artifactId>spring-context</artifactId>
     30 			<version>${spring-framework.version}</version>
     31 		</dependency>
     32 	</dependencies>
     33 </project>
     34 
    View Code

    2) 编写功能类Bean

      1 package com.ws.study.one;
      2 
      3 import org.springframework.stereotype.Service;
      4 
      5 // @Service注解声明当前FunctionService类是Spring管理的一个Bean
      6 @Service
      7 public class FunctionService {
      8 	public String sayHello(String word){
      9 		return "Hello " + word + " !";
     10 	}
     11 }
    View Code

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

      1 package com.ws.study.one;
      2 
      3 import org.springframework.beans.factory.annotation.Autowired;
      4 import org.springframework.stereotype.Service;
      5 
      6 // @Service注解声明当前类是Spring管理的一个Bean
      7 @Service
      8 public class UseFunctionService {
      9 
     10 	// @Autowired实体将FunctionService的实体Bean注入到UseFunctionService中,
     11 	// 进而使UseFunctionService具备FunctionService的功能
     12 	@Autowired
     13 	FunctionService functionService;
     14 
     15 	public String sayHello(String word){
     16 		return functionService.sayHello(word);
     17 	}
     18 }
     19 
    View Code

    4) 配置类

      1 package com.ws.study.one;
      2 
      3 import org.springframework.context.annotation.ComponentScan;
      4 import org.springframework.stereotype.Component;
      5 
      6 // @Component声明当前类是一个配置类
      7 @Component
      8 // 使用@ComponentScan,自动扫描包下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
      9 @ComponentScan("com.ws.study.one")
     10 public class DiConfig {
     11 
     12 }
     13 
    View Code

    5) 运行类

      1 package com.ws.study.one;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 	public static void main(String[] args) {
      7 		// 使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数
      8 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class);
      9 
     10 		// 获取声明配置的UseFunctionService的Bean
     11 		UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
     12 
     13 		System.out.println(useFunctionService.sayHello("di"));
     14 
     15 		context.close();
     16 	}
     17 }
     18 
    View Code

    6) 运行结果

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

    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) 编写功能类

      1 package com.ws.study.javaconfig;
      2 
      3 // 此处没有@Service声明的Bean
      4 public class FunctionService {
      5 	public String sayHello(String word){
      6 		return "Hello " + word + " !";
      7 	}
      8 }
      9 
    View Code

    2) 使用功能类

      1 package com.ws.study.javaconfig;
      2 
      3 //此处没有@Service声明的Bean
      4 public class UseFunctionService {
      5 	// 此处没有@Autowired声明的Bean
      6 	FunctionService functionService;
      7 
      8 	public void setFunctionService(FunctionService functionService) {
      9 		this.functionService = functionService;
     10 	}
     11 
     12 	public String sayHello(String word){
     13 		return functionService.sayHello(word);
     14 	}
     15 }
     16 
    View Code

    3) 配置类

      1 package com.ws.study.javaconfig;
      2 
      3 import org.springframework.context.annotation.Bean;
      4 import org.springframework.context.annotation.Configuration;
      5 
      6 // 使用@Configuration注解声明当前类是一个配置类。意味着这个类中可能存在0个或多个@Bean注解
      7 // 此处没有使用包扫描,是因为所有的Bean都在此类中定义了
      8 @Configuration
      9 public class JavaConfig {
     10 
     11 	// 使用@Bean注解声明当前方法FunctionService的返回值是一个Bean,Bean的名称是方法名
     12 	@Bean
     13 	public FunctionService functionService(){
     14 		return new FunctionService();
     15 	}
     16 
     17 	@Bean
     18 	public UseFunctionService useFunctionService(){
     19 		UseFunctionService useFunctionService = new UseFunctionService();
     20 		// 注入FunctionService的Bean时候直接调用functionService()
     21 		useFunctionService.setFunctionService(functionService());
     22 		return useFunctionService;
     23 	}
     24 
     25 //	// 另外一种注解方式,直接将FunctionService作为参数给useFunctionService()
     26 //	// 在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中写入
     27 //	@Bean
     28 //	public UseFunctionService useFunctionService(FunctionService functionService){
     29 //		UseFunctionService useFunctionService = new UseFunctionService();
     30 //		useFunctionService.setFunctionService(functionService);
     31 //		return useFunctionService;
     32 //	}
     33 }
     34 
    View Code

    4) 运行类

      1 package com.ws.study.javaconfig;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 	public static void main(String[] args) {
      7 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
      8 
      9 		UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
     10 
     11 		System.out.println(useFunctionService.sayHello("java config"));
     12 
     13 		context.close();
     14 	}
     15 }
     16 
    View Code

    5) 运行结果

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

    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依赖

      1 		<!-- spring aop支持 -->
      2 		<dependency>
      3 			<groupId>org.springframework</groupId>
      4 			<artifactId>spring-aop</artifactId>
      5 			<version>${spring-framework.version}</version>
      6 		</dependency>
      7 		<!-- aspectj支持 -->
      8 		<dependency>
      9 			<groupId>org.aspectj</groupId>
     10 			<artifactId>aspectjrt</artifactId>
     11 			<version>1.8.6</version>
     12 		</dependency>
     13 		<dependency>
     14 			<groupId>org.aspectj</groupId>
     15 			<artifactId>aspectjweaver</artifactId>
     16 			<version>1.8.5</version>
     17 		</dependency>
    View Code

    2) 编写拦截规则的注解

      1 package com.ws.study.aop;
      2 
      3 import java.lang.annotation.ElementType;
      4 import java.lang.annotation.Retention;
      5 import java.lang.annotation.RetentionPolicy;
      6 import java.lang.annotation.Target;
      7 
      8 // 注解本身没有功能
      9 // 注解和XML都是元数据
     10 // 注解的功能来自用这个注解的地方
     11 @Target(ElementType.METHOD)
     12 @Retention(RetentionPolicy.RUNTIME)
     13 public @interface Action {
     14 }
     15 
    View Code

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

      1 package com.ws.study.aop;
      2 
      3 import org.springframework.stereotype.Service;
      4 
      5 @Service
      6 public class DemoAnnotationService {
      7 	@Action(name = "注解式拦截的add操作")
      8 	public void add(){}
      9 }
     10 
    View Code

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

      1 package com.ws.study.aop;
      2 
      3 import org.springframework.stereotype.Service;
      4 
      5 @Service
      6 public class DemoMethodService {
      7 	public void add(){}
      8 }
      9 
    View Code

    5) 编写切面

      1 package com.ws.study.aop;
      2 
      3 import java.lang.reflect.Method;
      4 
      5 import org.aspectj.lang.JoinPoint;
      6 import org.aspectj.lang.annotation.After;
      7 import org.aspectj.lang.annotation.Aspect;
      8 import org.aspectj.lang.annotation.Before;
      9 import org.aspectj.lang.annotation.Pointcut;
     10 import org.aspectj.lang.reflect.MethodSignature;
     11 import org.springframework.stereotype.Component;
     12 
     13 // @Aspect注解声明一个切面
     14 @Aspect
     15 // @Component让此切面成为Spring容器管理的Bean
     16 @Component
     17 public class LogAspect {
     18 
     19 	// @Pointcut注解声明切点
     20 	@Pointcut("@annotation(com.ws.study.aop.Action)")
     21 	public void annotationPointCut(){};
     22 
     23 	// 通过@After注解声明一个建言,并使用@PointCut定义的切点
     24 	@After("annotationPointCut()")
     25 	public void after(JoinPoint joinpoint){
     26 		MethodSignature signature = (MethodSignature) joinpoint.getSignature();
     27 		Method method = signature.getMethod();
     28 		Action action = method.getAnnotation(Action.class);
     29 		// 通过反射可获取注解上的属性,然后做日志记录相关的操作
     30 		System.out.println("注解式拦截:"+action.name());
     31 	}
     32 
     33 	// 通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数
     34 	@Before("execution(* com.ws.study.aop.DemoMethodService.*(..))")
     35 	public void before(JoinPoint joinPoint){
     36 		MethodSignature signature = (MethodSignature)joinPoint.getSignature();
     37 		Method method = signature.getMethod();
     38 		System.out.println("方法规则式拦截: "+method.getName());
     39 	}
     40 }
     41 
    View Code

    6) 配置类

      1 package com.ws.study.aop;
      2 
      3 import org.springframework.context.annotation.ComponentScan;
      4 import org.springframework.context.annotation.Configuration;
      5 import org.springframework.context.annotation.EnableAspectJAutoProxy;
      6 
      7 @Configuration
      8 @ComponentScan("com.ws.study.aop")
      9 // 使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持
     10 @EnableAspectJAutoProxy
     11 public class AopConfig {
     12 
     13 }
     14 
    View Code

    7) 运行类

      1 package com.ws.study.aop;
      2 
      3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      4 
      5 public class Main {
      6 
      7 	public static void main(String[] args) {
      8 		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
      9 
     10 		DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
     11 		demoAnnotationService.add();
     12 
     13 		DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
     14 		demoMethodService.add();
     15 
     16 		context.close();
     17 	}
     18 
     19 }
     20 
    View Code

    8) 运行结果

      1 五月 30, 2018 10:06:14 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
      2 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy
      3 注解式拦截:注解式拦截的add操作
      4 方法规则式拦截: add
      5 五月 30, 2018 10:12:09 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
      6 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy
      7 
    View Code
  • 相关阅读:
    病毒木马查杀实战第017篇:U盘病毒之专杀工具的编写
    病毒木马查杀实战第016篇:U盘病毒之逆向分析
    病毒木马查杀实战第015篇:U盘病毒之脱壳研究
    病毒木马查杀实战第014篇:U盘病毒之手动查杀
    病毒木马查杀实战第024篇:MBR病毒之编程解析引导区
    病毒木马查杀实战第023篇:MBR病毒之引导区的解析
    缓冲区溢出分析第11课:整数溢出的原理
    缓冲区溢出分析第10课:Winamp缓冲区溢出研究
    Backdoor.Zegost木马病毒分析(一)
    缓冲区溢出分析第09课:MS06-040漏洞研究——深入挖掘
  • 原文地址:https://www.cnblogs.com/mengrennwpu/p/9108592.html
Copyright © 2020-2023  润新知