控制反转:是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度
控制反转常用的实现方式是依赖注入DI
通过控制反转,对象在被创建的时候,由系统的外部实体,将其所依赖的对象的引用传递(注入)进来,而不是系统内部进行对象的创建
具体实现:Spring Framework
以HelloWord程序为例
在面向对象的思想(OOP)的指导下,可将程序分为三个模块:
- 从持久化数据(文件、数据库等)中读取字符串
- 对读取的数据进行处理(编码、格式等)
- 将数据展现在用户界面(命令行、GUI、HTML等)
针对上述三个功能可写出三个类:
- FileHelloStr类:从持久化数据中读取信息
- HelloWorld类:业务逻辑,如添加Software后缀
- HelloWorldClient:将信息输出到命令行
存在的问题:
- HelloWorld类依赖于FileHelloWord类
- HelloWorldClient类依赖于HelloWorld类
- 系统的各部分之间相互依赖,导致可维护性和可扩展性差,不适合大型、企业级软件开发
解决方案:
- 面向接口的编程思想,将业务逻辑层(HelloWorld)和DAO层(FileHelloStr)的耦合消除
- 业务逻辑针对接口 *** 作,对具体的DAO类的 *** 作,委托给外部类
工厂模式分析:
- 业务逻辑、数据访问和界面逻辑三者之间完全解耦
- 工厂类负责创建和集成应用所需的各类对象
- 借助依赖注入(DI)和工厂模式实现了控制反转(IoC)
- 用于降低耦合度,实现方式为依赖注入
- 由系统外部实体将依赖的对象注入进来(不用new)
- 调用方引用一个接口或类就可以获得对象
IoC核心思想:解耦合,将组件的构建和组件的使用分开,实现每个组件时只考虑组件内部的事情,要点是明确和定义组件间的接口
IoC实现基础:面向接口编程 + 工厂模式 + 依赖注入
依赖注入
构造注入
<constructor-arg>
<bean name="对象名" class="类从哪创建">
<constructor-arg>
<ref bean="fileHello">
constructor-arg>
bean>
设值注入
<property>
<bean id="userBiz" class="UserBizImpl">
<property name="userDAO" ref="userDAO"/>
bean>
区别
- 设值注入支持大部分依赖注入,构造注入不支持
- 设值注入不会重写构造方法的值
- 设值注入不能保证某种依赖是否已经被注入,构造注入不允许生成依赖关系不完整的对象
- 设值注入使DAO,Impl,Service,ServiceImpl,配置applicationContext.xml实现
构造注入使用ServiceImpl,配置applicationContext.xml实现
Spring IoC中最核心的组件时工厂类
- Spring创建时通过Bean工厂来实现控制反转和依赖注入的,从而达到管理任意类型的应用对象的目的
- Bean工厂使用统一的方式装配所有的应用对象,时实例化、配置和管理Bean的容器,是Spring其他组件服务的基础
- Spring框架中,最基本的Bean工厂是接口BeanFactory
- ApplicationContext构建在BeanFactory基础之上。除了具有BeanFactory的功能之外,还添加了大量的功能,如Spring IoC集成、国际化资源、事件机制。
FileSystemXmlApplicationContext:可将配置文件放在项目的任何地方,但需要告知
ClassPathXmlApplicationContext:将配置文件放在项目的根目录下
Spring Bean管理- 由Ioc容器初始化,装配,管理的类
- Spring框架是实例化,配置,管理Bean的容器,通过Bean工厂实现Ioc和DI
- 管理分为xml和注解
Bean的基本配置
- Id和name
-
- 一般而言,通过id属性指明Bean的实例名
- id属性在整个IoC容器中必须唯一
- 如果Bean的名称中含有特殊字符,就是用name属性进行设置
- class
-
- class属性用于设置一个类的完整路径名
Bean管理——xml方式
作用域:
- singleton:Bean以单实例的方式存在,即在Spring IoC容器中只存在一个实例
- prototype:每次调用getBean()时都会返回一个新的实例
- request:仅适用Web环境。每次Http请求都会创建一个新的Bean
- session:仅适用Web环境。作用域等同HTTP session的效用
三种实例化方式:类构造器(默认无参构造方法)/静态工厂(简单工厂模式)/实例工厂(工厂方法模式)
//Bean的实例化
//...............................................................
//类构造器(class中填类名)
//如果有参需要使用<constructor-arg>
<bean id="exampleBean" class="examples.ExampleBean"/>
//...............................................................
//静态工厂
//在class助兴中填静态工厂类名,factory-method属性中填方法名
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
//
public class ClientService{
private static ClientService clientService=new ClientService();
private ClientService(){}
public static ClientService createInstance(){
//1.私有(别人不可用)
//2.对外获取方法需为静态(可以直接使用类名调用方法)
return clientService;
}
}
//...............................................................
//实例工厂
//先定义工厂bean,再设定factory-method和factory-bean属性
<bean id="serviceLocator" class="examples.DefaultServiceLocator" >
bean>
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>
//
public class DefaultServiceLocator(){
private static ClientService clientService=new ClientServiceImpl();
private DefaultServiceLocator(){}
public ClientService createClientServiceInstance(){
return clientService;
}
}
Bean的生命周期
实例化、属性赋值、初始化、销毁
bean的依赖注入:构造注入/设值注入
//构造注入
<beans>
<bean id="Foo" class="x.y.Foo">
//Foo下有两个属性
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
bean>
<bean id="bar" class="x.y.Bar">
<bean id="baz" class="x.y.Baz">
beans>
//
package x,y;
public class Foo{
public Foo(Bar bar,Baz baz){
//...
}
}
//...............................................................
//设值注入
<bean id="exampleBean" class="examples.ExampleBean">
<property name="beanOne"><ref bean="anotherExampleBean"/>
<property name="beanTwo"><ref bean="yetAnotherBean"/>
<property name="integerProperty" value="1">
bean>
<bean id="anotherExampleBean" class="examples.AnotherBean">
<bean id="yetAnotherBean" class="examples.YetAnotherBean">
//
public class ExampleBean(){
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne){
this.beanOne=beanOne;
}
public void setBeanTwo(YetAnotherBean beanTwo){
this.beanTwo=beanTwo;
}
public void setintegerProperty(int i){
this.i=i;
}
}
其他注入方式:
- 复杂数据类型注入:List、Set、Map
- p名称空间方式:p:<属性名>
- SpELl表达式语言:#{表达式}
Bean管理——注解方式
- @Component:用于一般意义的Bean注解
- @Repository:用于对DAO实现类的注解
- @Service:用于对Service业务逻辑类的注解
- @Controller:用于对Controller控制器的注解
- @Autowired:实现属性的自动注入
-
- @Autowired注解默认按类型进行自动注入,类型相同时则按照名称进行注入
- @Autowired注解的required属性用来指定一定要找到匹配的Bean
- @Resource:与@Autowired类似
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)