# spring
**Repository Path**: luzhizero/spring
## Basic Information
- **Project Name**: spring
- **Description**: 整理了spring的aop,ioc等功能
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-01-10
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# spring
spring中常用jar包:
Spring AOP:Spring的面向切面编程,提供AOP(面向切面编程)的实现
Spring Aspects:Spring提供的对AspectJ框架的整合
Spring Beans:Spring IOC的基础实现,包含访问配置文件、创建和管理bean等。
Spring Context:在基础IOC功能上提供扩展服务。
Spring Context Support:Spring context的扩展支持,用于MVC方面。
Spring Core:Spring的核心工具包
Spring expression:Spring表达式语言
Spring Instrument:Spring对服务器的代理接口
Spring Instrument Tomcat:Spring对tomcat连接池的集成
Spring JDBC:对JDBC的简单封装
Spring JMS:为简化jms api的使用而做的简单封装
Spring orm:整合第三方的orm实现,如hibernate,ibatis,jdo以及spring 的jpa实现
Spring oxm:Spring对于object/xml映射的支持,可以让JAVA与XML之间来回切换
Spring test:对JUNIT等测试框架的简单封装
Spring tx:为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。
Spring web:包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。
Spring webmvc:包含SpringMVC框架相关的所有类
idea创建spring项目
1.创建maven的项目后再pom中引入
```
org.springframework
spring-context
5.1.6.RELEASE
```
2.创建项目格式

3.右击resouces文件夹,创建applicationContext.xml配置文件

4.创建结果如下
```
```
关于控制反转
控制反转
IOC(Inverse Of Control)是Spring核心功能之一,“控制反转”(IOC) 将应用程序的配置和依赖性规范与实际的应用程序代码分开。
创建bean的方式
1.配置文件创建
1.1
```
```
1.2
但是有些特殊情况,对象并不是通过new 来进行创建,而是通过对象工厂的方式来创建,spring的配置文件也支持这种方式创建bean.我们在定义bean标签时需要,需要把的class属性配置为工厂类(或者把factory-bean属性配置为工厂类对象),使用属性factoryMethod来定义工厂类中获取此对象的方法。
创建一个dao,并为它写一个简单的工厂
```
public class MyDao {
public MyDao() {
System.out.println("mydao被创建");
}
}
```
```
public static MyDao getDao(){
System.out.println("DaoFactory的getdao方法被调用");
return new MyDao();
}
```
```
```
这里值得一提的是,工厂类方法必须是静态方法,如果方法不为静态的情况下,就以如下方式进行创建
```
```
1.3
spring的bean默认情况下都是单例的,如果需要创建非单例的项,则在bean标签中添加scope="prototype"来进行修改(4.0以前为singleton=”false”)
2.注解创建对象
常用注解:
@Component 该注解需要定义在类上,表示该类对象需要通过Spring来创建。
@Controller 该注解需要定义在控制层的类上,表示该类对象需要通过Spring来创建,@Controller层是spring mvc的注解,具有将请求进行转发,重定向的功能。
@Service 该注解需要定义在业务层的类上,表示该类对象需要通过Spring来创建,这个注解只是标注该类处于业务逻辑层。
@Repository 该注解需要定义在数据层的类上,表示该类对象需要通过Spring来创建,还注解还具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
上述4个注解的作用等同于标签,在使用这些注解时可以传入一个字符串作为bean id,如果没有传入bean id则默认bean id等于类名首字母小写。
3.通过@Configuration和@Bean的组合注解来进行对象的创建
```
@Configuration
public class ServiceConfigration {
@Bean(value = "myService")
public MyServiceImpl getMyServiceImpl(){
return new MyServiceImpl("张三");
}
}
```
注意:上述使用注解的方式进行bean创建时,需要在applicationContext.xml中声明添加了注解的这些类所在的包名,这样Spring才能去扫描这些包,如果不配置注解将不生效。配置方式如下:
```
```
属性注入到bean中
1.property标签进行注入,name表示注入哪一个属性,ref为备注如的bean的id
```
```
这种方式还支持list,set和map注入,这里就不展开讲了.
2.@Autowired和@Resource
上述两个注解用于进行依赖注入,只不过@Autowired按属性类型自动注入,而@Resource默认按属性名称自动注入。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性作为bean id去容器中查找,而type属性则解析为bean的类型。所以如果使用name属性,则优先通过属性名称自动注入,而使用type属性时则使用类型匹配自动注入策略。如果既不指定name也不指定type属性,这时将通过优先用过属性名称自动注入策略。无论使用@Resource还是@AutoWired如果匹配策略是按照类型匹配,这时Spring容器中有超过1个相同类型对象时,就会出现异常。
3.构造函数注入
当我们创建bean时希望在里面的属性添加值得时候可以在bean标签内部添加标签来注入属性值,类必须给与对应的构造函数.多个属性需要多个标签,并且顺序与类相同.
```
张三
```
springbean的生命周期

各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
Bean级生命周期接口方法: 这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
容器级生命周期接口方法: 这个包括了InstantiationAwareBeanPostProcessor 和BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法: 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
一、创建和属性注入
1.Bean的创建,由BeanFactory读取Bean定义文件,并生成各个实例
2.Setter注入,执行Bean的属性依赖注入
二、将容器和bean本身的信息暴露出来便于使用
3.BeanNameAware的setBeanName(), 如果实现该接口,则执行其setBeanName方法
4.BeanFactoryAware的setBeanFactory(),如果实现该接口,则执行其setBeanFactory方法
4.ApplicationContext的setApplicationContext(),如果实现该接口,则执行其setApplicationContext方法
三、初始化过程
5.BeanPostProcessor接口下的postProcessProperties(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processBeforeInitialization()方法
6.InitializingBean的afterPropertiesSet(),如果实现了该接口,则执行其afterPropertiesSet()方法
7.Bean定义文件中定义init-method
8.BeanPostProcessor接口的processAfterInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processAfterInitialization()方法
四、销毁过程
9.DisposableBean的destroy(),在容器关闭时,如果Bean类实现了该接口,则执行它的destroy()方法
10.Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法
下面以User类来进行bean的创建
```
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
}
public MyBeanFactoryPostProcessor() {
super();
System.out.println("MyBeanFactoryPostProcessor的构造方法被调用");
}
}
```
```
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!!");
// TODO Auto-generated constructor stub
}
//这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。这里要注意。
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
return arg0;
}
}
```
```
@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessProperties方法");
return super.postProcessProperties(pvs, bean, beanName);
}
}
```
```
package com.lzlearn.model;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
public class User implements BeanFactoryAware, BeanNameAware,InitializingBean, DisposableBean {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】注入属性name");
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
System.out.println("【注入属性】注入属性sex");
this.sex = sex;
}
public User(String name, String sex) {
System.out.println("User的全参构造被调用");
this.name = name;
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
public User() {
System.out.println("User的无参构造被调用");
}
private BeanFactory beanFactory;
private String beanName;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String s) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
this.beanName = s;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
// 通过的init-method属性指定的初始化方法
public void myInit() {
System.out.println("【init-method】调用的init-method属性指定的初始化方法");
}
@Override
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
}
// 通过的destroy-method属性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】调用的destroy-method属性指定的初始化方法");
}
}
```
```
package com.lzlearn.test;
import com.lzlearn.model.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
//读取配置文件
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("容器初始化成功");
//获取User的bean
User user = classPathXmlApplicationContext.getBean("user", User.class);
System.out.println(user);
System.out.println("开始销毁bean容器");
((ClassPathXmlApplicationContext)classPathXmlApplicationContext).registerShutdownHook();
}
}
```
```
```
测试结果如下

关于AOP
在使用AOP时,需要了解动态代理,(JDK和CGlib)动态代理模式
AOP(Aspect Oriented Programming),即面向切面编程。AOP是对OOP(Object Oriented Programming,面向对象编程)的补充和完善。
OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理、事务管理等等,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
AOP核心概念:
JointPoint(连接点):
表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 JointPoint。连接点代表了时间,也就是何时去执行
Pointcut(切入点):
表示一组 JointPointt,是在程序中用表达式、正则对连接点的描述。
Execution (* com.woniu.service.*.*(..))
Advice(通知):
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。通知代表的所做的事情
Aspect(切面):
Aspect声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。切面就是对何时做什么事情的抽象。
目标对象
代理的目标对象
织入(weave)
将切面应用到目标对象并导致代理对象创建的过程
AOP有两种实现方式,分别为原生实现以及整合Aspect实现
首先创建拦截器来进行增强操作,除了前置和后置,也可以进行环绕增强
```
public class TranscationAdvice implements MethodBeforeAdvice , AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
//后置处理器
System.out.println("提供后置操作,如提交事务");
}
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
//前置处理器
System.out.println("提供前置操作,如开启事务");
}
}
```
创建一个MyService的接口以及其实现类MyServiceImpl
在xml中进行配置
```
```
调用
```
//读取配置文件
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = classPathXmlApplicationContext.getBean("proxy", MyService.class);
User user = myService.selectUser();
System.out.println(user);
```
执行结果

AOP整合Aspect框架实现AOP(注解版)
引入pom
```
org.aspectj
aspectjrt
1.9.2
org.aspectj
aspectjweaver
1.9.2
```
创建拦截器类,并交给spring托管
```
package com.lzlearn.config;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class TranscationConfig {
@Before("execution(* com.lzlearn.service.*.*(..))")
public void start(){
System.out.println("前置方法");
}
@AfterReturning("execution(* com.lzlearn.service.*.*(..))")
public void after(){
System.out.println("后置方法");
}
@After("execution(* com.lzlearn.service.*.*(..))")
public void finalMethod(){
System.out.println("最终方法");
}
@AfterThrowing("execution(* com.lzlearn.service.*.*(..))")
public void errMethod(){
System.out.println("异常方法");
}
}
```
或者进行环绕增强
```
@Around("execution(* com.lzlearn.service.*.*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint){
Object result = null;
try {
System.out.println("开启事务");
result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
System.out.println("提交事务");
} catch (Throwable throwable) {
System.out.println("回滚事务");
throwable.printStackTrace();
} finally {
System.out.println("关闭事务");
}
return result;
}
```
这里解释一下("execution(* com.lzlearn.service.*.*(..))")
1、execution(): 表达式主体。
2、第一个*号:表示返回类型, *号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.lzlearn.service包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数