Spring核心技术

Spring容器介绍

Spring IoC

Spring框架实现依赖IOC原则(依赖注入), 相比Bean直接构建对象, Spring框架则根据Bean之间的依赖创建对象, 并注入到Bean中, 对于传统的代码, 常见下面写法

public UserServiceImpl implements UserService {
	private CreditUserService creditUserService = new CreditUserService();
	public void order(...){
		creditUserService.addCredit(5);
	}
}

或者封装一下工厂类

private CreditUserService creditUserService = ServiceFactory.getService(CreditUserService.class);

Spring中, 如果你的Bean是通过Spring管理的, Spring框架来帮助你完成这些事情, 开发人员只是需要声明依赖关系

@Service
public UserService {
	@Autowired
	private CreditUserService creditUserService;
	public void order (...) {
		...
		creditUserService.addCredit(5);
	}
}

Bean通过注解@Service声明一个Spring管理的Bean, Spring容器会扫描classpath下的所有类, 找到带有@Service注解的UserService类, 并根据Spring注解对其进行初始化和增强, 如果发现此类属性, creditUserService也有注解@Autowired, 则会从Spring容器中查找一个已经初始化好的CreditUserService, 如果没有会将其初始化

Spring常用注解

  • Controller: 声明此类是一个MVC类, 通常与RequestMapping一起使用
    @Controller
    @RequestMapping("/user")
    public class UserController {
    	@RequestMapping("/get/{id}")
    	public String getUser(@PathVariable String id){
    		...
    	}
    }
    
  • Service: 声明此类是一个业务类, 通常与@Transactional 一起使用
    @Service
    @Transactional
    public class UserServiceImpl implements UserService {
    	public void order(...){
    		...
    	}
    }
    
  • Repository: 声明此类是一个数据库或者其他NoSQL访问类
    @Repository
    public class UserDao implements CurdDao<User, String> {
    
    }
    
  • ResetController: 同Controller, 用于REST服务
  • Component: 声明此类是一个Spring管理的类
  • Configuration: 声明此类是一个配置类, 通常与Bean配合使用
    // DataSourceConfig为一个容器配置类
    @Configuration
    public class DataSourceConfig {
    	@Bean(name = "dataSource")
    	public DataSource dataSource(Environment env) {
    		HiKariDataSource ds = new HiKariDataSource();
    		ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
    		db.setUsername(env.getProperty("spring.datasource.username"));
    		db.setPassword(env.getProperty("spring.datasource.password"));
    		db.setDirverClassName(env.getProperty("spring.datasource.driver-class-name"));
    		return db;
    	}
    }
    
  • Bean: 作用在方法上, 声明该方法执行的结果是一个Spring容器管理的Bean

Bean注解详解

Spring负责实例化Bean, 开发者可以提供一系列的回调函数, 用于进一步配置Bean, 其中包含@PostConstruct(初始化)注解和@PreDestory(待销毁)

@Component
public class ExampleBean {
	@PostConstruct
	public void init() {}
}
public class ExampleBean {
	@PreDestory
	public void cleanup() {}
}

Spring还提供了其他方法为Bean周期提供回调, 可以实现InitializingBean接口的afterPropertiesSet()初始化Bean,和实现DisposableBeandestroy()来销毁Bean

Spring有两种方式可以引入Bean, 根据名字和根据类型
根据名字引用Bean
定义

@Service
@Qualifier("exampleBean")
public class ExampleBean {}

引用

@Service
public AnotherExampleBean{
	@Qualifier("exampleBean") ExampleBean bean;
}

根据类型引用Bean
定义

@Service
public class ExampleBean{}

引用

@Service
public class AnotherExampleBean{
	@Autowried ExampleBean bean;
}

Spring AOP

AOP几点概念

  • Aspect: Aspect声明了类似于Java中的类声明, 在Aspect中会包含一些PointcutAdvice
  • Joint Point: 表示在程序中明确定义的点, 包括方法调用, 对类成员调用, 以及异常处理程序块执行Spring中的Joint point只支持方法调用
  • Pointcut: 表示一组Joint point, 如方法名, 参数类型, 返回类型, 这些Joint point通过逻辑关系组合起来, 它定义了对应的Advice将要发生的地方, Pointcut就是一种表达式, 来判断Joint point方法调用中执行Advice操作
  • Advice: 定义了在Pointcut里面定义的程序点具体需要做的操作, 他通过before, around, after(return, throw, finally), 来区别是在哪一个Joint point之前或者之后要调用的代码
    - before: 在执行方法前调用Advice, 譬如cache需要判断是否有记录存在
    - around: 环绕通知再, 执行之前呵之后调用Advice
    - after: 在执行方法之后调用Advice, after return正常返回时调用, after throw失败时调用
  • AOP Proxy: AOP Proxy也是Java对象,由AOP框架创建, 用来完成上述动作
  • Weaving: 实现上述切片编程的代码植入, 可在编译时通过AspectJ Compiler也可以在运行时刻, Spring框架都是在运行时刻生成代理

SpringBoot 中使用 AOP

引入AOP依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

用法

import org.aspectj.lang.ProcessdingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;

@Configuration
@Aspect
public class AOPConfig {
	@Around("@within(org.springframework.stereotype.Controller)")
	public Object simpleAop(final ProceedingJoinPoint pjp) throws Throwable {
		try {
			Object[] agrs = pjp.getArgs();
			System.out.println("args:" + Arrays.asList(args));
			// 调用原有方法
			Object o = pjp.proceed();
			System.out.println("return :" + o);
			return o;
		} catch (Throwable e) {
			throw e;
		}
	}
}

代码解析

  1. @Configuration: 声明这是一个Spring管理配置Bean, 可以理解为引起Spring的注意
  2. @Aspect: 声明了这是一个切面类
  3. @Around: 声明了一个表达式, 描述要植入的特性, @within表示目标类型带有注解, 参数为org.springframework.stereotype.Controller这意味着, Spring的这个Controller方法在被调用时, 都会执行@Around的方法simpleAop
  4. simpleAop: 用来植入代码, 七参数为ProceedingJoinPoint, 上面实例将参数方法取出来, 打印到控制台
  5. pjp.proceed: 通常情况下, 执行完切面代码, 还需要继续执行应用代码, proceed()方法则会继续调用原有业务逻辑, 并将返回对象正常返回

AOP常用表达式

execution(public * *(..)) // 所有`public`方法, 后面星号代表路径名和方法名字
execution(\* set\*(..)) // 所有`set`开头的方法
execution(public set*(...)) // 所有以`set`开头的`public`方法
execution(public com.xyz.service.* set*(...)) // 位于`com.xyz.service`包下所有以`set`开头的`public`方法
target(com.xyz.service.CommonService) // // 所有实现了`CommonService`接口的类和方法
@target(com.springframework.transaction.annotation.Transactional) // 所有`@Transactional`注解的方法
@within(org.springframework.stereotype.Controller) // 类型声明了所有`@Controller`注解的所有方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值