Spring核心功能
DI(IOC)
何谓DI(IOC)
DI(依赖注入)是spring的核心功能之一。
Dependency Injection 和 Inversion of Control 其实就是一个东西的两种不同的说法而已。本质上是一回事。Dependency Injection 是一个程序设计模式和架构模型, 一些时候也称作 Inversion of Control,尽管在技术上来讲,Dependency Injection 是一个 Inversion of Control 的特殊实现,Dependency Injection 是指一个对象应用另外一个对象来提供一个特殊的能力,例如:把一个数据库连接以参数的形式传到一个对象的结构方法里面而不是在那个对象内部自行创建一个连接。Inversion of Control 和 Dependency Injection 的基本思想就是把类的依赖从类内部转化到外部以减少依赖。 应用Inversion of Control,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,Inversion of Control 是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转。IoC是通过处理对象定义依赖的方式来工作,也就是说,一起协作的对象,要么通过构造函数参数来获得,要么在构造之后给对象设置属性来获得,要么从工厂方法返回的方式来获得。容器先创建bean,然后再注入这些依赖。这个获取过程是完全反过来的,所以命名为控制反转(IoC)。
DI能够删除任何特定的依赖于别的类或第三方接口的类,并且能够在初始化构造时加载要依赖的类。DI的优点是你可以依赖类的实现而并不需要更改你的代码。你甚至可以在接口不变的条件下重写依赖的实现而不用改变你的编码,即面向接口的编程。
DI实现方式
构造器注入:通过构造器注入,能使当前实例作为不可变对象,并且能确保所有需要的依赖都是非空的.更进一步,构造器注入返回给客户代码的是一个完全初始化状态的对象.
Setter方法注入:Setter方法注入作为构造器注入的补充实现.能注入可选的有默认值的依赖.否则,会随处校验依赖的非空与否.
自动装配
@Autowired:即通过注解自动装配,默认方式是byType.
@Resource:即通过注解自动装配,默认方式是byName.
@javax.inject.Inject:类似与@Autowired
@Qualifier:指定实现不同的限定符,在具体注入时,通过该注解具体限定
Spring容器会在容器加载时校验依赖非空和循环依赖.在初始化Bean时,Spring会在bean真正创建之前尽可能晚的设置属性和解决依赖关系
bean定义和依赖实现方式
XML文本配置文件通过上面的方式来定义一个bean,通过在bean中添加依赖来达到目的.
主要依赖方式有:
构造器注入.
Setter属性方法注入
通过XML配置文件构造Spring beans和依赖缺失了编译时的类型检查,比如构造器参数的类型错误,甚至是构造器错误的参数只有在ApplicationContext容器在运行时构造时才会检查。
使用注解
通过配置自动注解扫描的根包,并且在bean上使用注解@Component(@Service,@Repositoty,@javax.inject.Named)等标示他是一个bean.
通过如上配置自动扫描根包下的类,并作自动注解绑定
解释下context:annotation-config/:
它的作用是隐式的向Spring容器注册这4个BeanPostProcessor.注册这4个bean处理器主要的作用是为了你的系统能够识别相应的注解。
如果想使用@Autowired,@PersistenceContext,@Required,@Resource,@PostConstruct,@PreDestroy,就需要按照传统声明一条一条去声明注解Bean,就会显得十分繁琐.
因此如果在Spring的配置文件中事先加上context:annotation-config/这样一条配置的话,那么所有注解的传统声明就可以被忽略,即不用在写传统的声明,Spring会自动完成声明。解释下context:component-scan/:
作用是让Bean定义注解工作起来,也就是上述传统声明方式.它的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
值得注意的是context:component-scan/不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor),因此当使用context:component-scan/后,就可以将context:annotation-config/移除了。通过如上配置定义一个bean,并作自动绑定
主要注解依赖方式有:
@Autowired:即通过注解自动装配,默认方式是byType.
@Resource:即通过注解自动装配,默认方式是byName.
@javax.inject.Inject:类似与@Autowired
当通过@Autowired注入时,默认是通过类型匹配具体的实现类的,但是如果接口有多个实现类,Spring容器是没法做选择的,有两种方式解决这个问题:
@Primary注解,指定当有多个候选实现时,首选这个实现.
[email protected]注解指定不同实现不同的限定符,在具体注入时,通过该注解具体限定.
解释下@Autowired:
可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。@Autowired的标注位置不同。
它们都会在Spring在初始化这个bean时,自动装配这个属性。注解之后就不需要set/get方法了。
其中@Inject 和@Named是JSR 330 Standard Annotations.s
通过Spring提供的扩展方式做处理
可以通过init-method的方式来实现初始化注入,还可以通过实现``InitializingBean`接口来实现,但此种方式对业务代码有侵入性,少用。
bean加载过程可以通过设置factory-method的方式设置工厂方法,来设置一些静态属性
调用getter方法,用工厂Bean PropertyPathFactoryBean
调用普通方法(实例方法或者类方法),用工厂Bean MethodInvokingFactoryBean
获取Field的值,用工厂Bean FieldRetrievingFactoryBean
@Configuration&@Bean
@Bean可以出现在@[email protected],其中@Configuration类似于xml中的,而@Component类似于xml中的,@Component可以作为@Configuration的替代。
但是有一些问题:当我们使用@Bean注解在例如@Component作用的class里面时,将会发生一种称之为注解@Bean的lite mode出现,这种不会使用CGLIB代理.所以只要我在@Bean修饰的方法之间不相互编码调用,代码将会很好的运作.
下面是@Bean的lite mode示例:上述代码在new SimpleBeanConsumer(simpleBean())这一步实例化bean时,不会将第一步@Bean实例化的bean自动注入到simpleBeanConsumerbean中,而是重新用simpleBean(),生成一个新的SimpleBean 实例.而@Configuration则不会发生上述情况,代码如下:
要改善上述问题,可以通过以下方式实现:
通过将@Bean生成的bean Autowired到属性上,并在@Bean实例化SimpleBeanConsumerbean时传入此属性,来达到目的.
参考: Spring @Configuration vs @Componentbean的作用域
session
request
prototype
singleton
application
其中singleton是容器级别的,即一个容器一个bean实例,spring的单例实例缓存在ConcurrentHashMap中;而GOF的单例模式是基于ClassLoader的,即一个类加载器只能有一个实例
通过bean后处理来增强功能
BeanFactoryPostProcessor
通过实现BeanFactoryPostProcessor,对bean配置的元数据做一些处理(可以改变初始化bean的内容),比如为安全考虑的数据库密码加密配置在配置文件中,在jdbc连接数据库时需要解密可以通过扩展BeanFactoryPostProcessor来实现.
BeanPostProcessor
通过实现BeanPostProcessor,可以实现在Spring容器在完成Bean的实例化,配置和其他的初始化前后做一些自己的业务处理,比如我们可以统计自定义的的Bean集合.
aop注入式编码式
编码式通过在代码中加入事务管理来达到目的,但由于事务逻辑与主业务逻辑没啥关系,代码没必要紧耦合在一起,所以此方法不怎么使用.
JPA知识点
mapping pojo结构详述
啥事不干,先上一个多对多关系的例子.
@Entity非常有幸能和大家一起分享知识和经验,正是由于大家的无私分享,才让我们得以成长和进步,我最近几年来都很少分享东西,有时候是因为工作很忙没有时间写点东西,有时候也是因为自己懒或是没有什么新东西可以分享给大家的。最后也希望大家对我的分享不足之处给予批评指正,一起进步!
最后分享一个java大牛微信:dongnaobest20
微信扫码领取java全套资料哦~