Spring ioc

Spring 框架优点:
动态解耦   方便测试    降低java ee API的难度   方便集成各种框架  
支持AOP   声明式事务的支持    自定义功能模块

三层架构:
dao层          数据访问层/数据交互层     与数据库进行增删改查操作
 service层              业务逻辑层         处理业务逻辑,如登录的判断
 web层         表现层/用户访问层     接收请求,反馈(页面/数据)


IOC:控制反转 容器   IOC容器
负责管理各种对象的生命周期
DI:依赖注入
属性注入:
 set方式的注入:
     普通属性--》必须具备set方法,空参构造器
      集合属性--》
           List
               <list>
             <value></value>  
            </list>
   构造器注入(无参构造器进行反射)
    工厂类
           实现factoryBean接口
           实例工厂类对象
           静态工厂
自动注入(自动注入类与类之间的关联关系)
Spring管理对象所声明的生命周期
自定义属性编辑器
自定义事件
注解
 
出现全限定类名:反射
创建对象:new
                 spring的容器

  去配置属性(property)的注入
 
如何去配置  set类的注入
 pojo类
 是一个简单的java类,用来反映实体的属性

数据
web网页:json格式的字符串或者数组
                  {
               key1:value1,
               key2:value2
                 }
   java用一个类来描述数据
 gender boolean  true  "男"
 javaBean -->组件

AOP:面向切面编程

宗旨:简化操作  降低耦合
springframework   web date aop test core
核心:core aop

三层架构
 web层 接收数据
 service 业务处理
 dao  和数据库交互

 Spring帮助创建对象
将原本写死的代码,分开,再在运行期间,动态的将各部分代码结合在一起
将类和类之间的关联关系进行处理

Spring:轻量级框架
容器:1.GUI 2web容器 3Spring容器

Spring 的ioc和aop功能(面试重点)

Spring功能:
1.帮助程序员管理了对象的生命周期
2.attribute对应的属性,property对应的参数

Spring:配置文件--xml
1.Spring中如何帮助我们管理对象?
将要管理的对象,交给(配置)Spring容器
2.如何将对象配置给Spring容器
3,哪些对象可以配置给
4.配置到容器中的类对象叫什么
bean对象
5.配置进去后,有什么好处
反复使用

可以理解为我们帮项目找了一个管家
1.管理类对象的生命周期
2.将建立对象和对象之前的复杂关联关系
3.动态的结合代码

将主动变被动

BeanFactory接口
getBean(string name)
IOC核心容器:



核心:让Spring容器知道谁是工厂类
ioc:
//1 声明要读取的xml文件路径(如果有多个可以放在数组中)
//2 读取xml文件创建spring的容器contanier
//3 从容器container中根据配置的名字拿出需要使用的对象
//4 使用对象进行操作(对象中的需要的各种数据和依赖的其他对象早已经被spring的容器注入进来)


[1]set注入(当前这个类一定要有对应的set方法)
1.可以帮助我们管理对象的生命周期
2.可以构建对象和对象之间的关联关系
value字符串  ref引用对应的bean对象
applicationContext接口 继承了BeanFactory接口

[2]给对象中注入集合
list set
map <entry key ="" value=""/>
prop  <prop key="p1">a</prop>

[3]构造器注入
xml文件中有bean的配置,而且bean对应的java文件中有无参构造器通过反射调用无参构造器
1.根据参数类型  与bean中参数位置无关
问题:参数类型相同时无法区分
        构造器重载时无法区分(不会报错)
2.根据参数位置的下标(从0开始)
 <bean name="student" class="com.briup.bean.Student">
 <constructor-arg index="0" value="2"  ></constructor-arg>
 <constructor-arg index="1" value="xioawu"  ></constructor-arg>
 <constructor-arg index="2" value="20"  ></constructor-arg>
 </bean>  
   因为构造器中参数的位置,可能会造成数据错误
  <bean name="student" class="com.briup.bean.Student">
 <constructor-arg index="0" value="2" name="id" ></constructor-arg>
 <constructor-arg index="1" value="xioawu" name="name" ></constructor-arg>
 <constructor-arg index="2" value="20" name="age" ></constructor-arg>
 </bean>  
构造器重载:加个name
(一般用构造器注入)

[4]自动注入 auowire
自动建立类与类之间的关联关系
autowire="byName":找set方法中同名的bean
            spring容器会到当前的类中找property的名字,然后
            再根据这个名字去spring容器中找有没有和这个property
            名字相同的对象,有的话,就把这个对象当做参数放到
            setXxxx这个方法里面注入进来.

autowire="byType" 根据bean对象的类型进行匹配,bean需要唯一  找到多个,报错
                  spring容器会根据当前类中的set方法里面参数的类型,
              去容器中找相匹配的对象,如果没找到就算了,如果找到
              一个就注入进来,如果找到多个,那么就会报错了.

在根标签中指定 default-autowire="byName" bean中不用再配置byName
局部配置覆盖全局配置

[5]继承
原来类与类的继承 耦合太高
保存父类原有的方法的同时添加一些新方法
 <bean name="tSon" parent="teacher">
//表示创建一个类,tSon,为teacher bean的子类
注意:调用tSon时,tSon为父类型的
Teacher son = (Teacher) container.getBean("tSon");

子类和父类的内存地址是否相同?
不同
可以修改父类中的值    (父类不改变,子类中的值不再是继承的值)
可以增加父类中没有的值

父类中被abstract修饰 (抽象类不能创建类对象)
<bean name="teacher" class="com.briup.bean.Teacher" abstract="true">
默认bean单例
 abstract="true" 父类只能被继承,不能再去修改,只能子类修改
多个子类创建不同的对象 互不影响

[6]Bean对象在IOC容器中的生命周期
完整的生命周期 life 10步
从容器中取值时,容器已经构建好bean对象,是否取值对构建bean对象无影响
调用container.destroy()方法会销毁单例对象(非单例对象无法销毁)
不完整的生命周期

lazy-init="true"只有使用时才创建
问题:一个类创建时需要关联另一个类,另一个类没有创建,这个类就创建不出来

非单例:每次使用时才会创建对象(因为每次拿时创建的是不同的对象)
设置成非单例      scope="prototype"

[7]xml文件导入其他xml文件配置
   <!-- 将多个xml配置文件,合并到一个配置文件 -->使用相对路径
<import resource="student.xml"/>
<import resource="teacher.xml"/>
String[] path = {"com/briup/ioc/imp/teacher.xml","com/briup/ioc/imp/student.xml"};
String[] path = {"com/briup/ioc/imp/import.xml"};

spring容器创建bean对象的方式
spring java里面的类 bean
           java里面的属性  property
1.普通bean标签的配置  (反射一定要无参的构造器)
2.工厂模式的生产---》得到的实例对象bean   产品对象
普通的工厂
静态工厂
获得产品的时候 静态方法
配置方法 factory-method
动态工厂
获得产品的时候 非静态方法
配置方法 factory-method

工厂类 批量创建bean对象
xxxFactory
目的:获取xxx
<bean name="fa" class="class...XXFactory">
核心:让spring容器知道谁是工厂类
           让spring容器知道调用哪个工厂方法

 
[8]配置工厂类  通过工厂类获得实例
1.该类是个工厂类,(实现FactoryBean接口,表示这是个工厂类  返回值为目的对象)
public Connection getObject() throws Exception {}
将来想要得到的对象的类型
public Class<?> getObjectType() {}
是否单例
public boolean isSingleton() {return false;}
2.写xml文件 普通的bean对象
 <!-- spring提供的类,用来读取外部配置文件  -->
3.test
因为这个类是一个工厂类,所以我们用名字conn在容器中拿对象的时候,
拿到并不是这个工厂类对象,而是这个工厂类对象调用完工厂方法后所返回的对象.

[9]实例工厂获得bean对象
1.类中不用实现接口  普通的类 get set方法+返回工厂类对象的方法
public Connection getConnection() throws Exception {
        Class.forName(driver);
        return DriverManager.getConnection(url, username, password);
    }
  2.xml  普通的bean+conn为getConnection()返回的对象
<bean name="conn" factory-bean="factory2" factory-method="getConnection">
    </bean>
3.test
Connection conn = (Connection) container.getBean("conn");
实例工厂与普通工厂相比,不用实现接口,多一个getConnection方法,xml中多了一个获取连接的bean

[10]静态工厂
1.类中  静态属性+静态代码块 +getConnection
(属性值放在代码块中 所有的值固定)
使用static?因为static类型的属性、代码块在类加载之前构建
2.不用写bean
<bean name="factory3"
   class="com.briup.ioc.staticFactory.ConnectionFactory"
   factory-method="getConnection"></bean>
3.获取connection类型的bean

自定义
[11]自定义属性编辑器
Spring中我们可以使用属性编辑器来将特定的字符串转换为对象
        String--转换-->object
自定义编辑器类  继承PropertyEditorSupport(用于把字符串转成特定的类型)
Spring在注入时,如果遇到类型不一致(例如需要Address类型但是用户传了个String)则会去调用相应的属性编辑器进行转换
spring会调用属性编辑器的setAsText(String str)进行处理用户传的字符串,并调用getValue()方法获取处理后得到的对象
在代码中处理完后需要调用setValue方法,要不然spring调用getValue方法拿不到处理后转换成的对象
setAsText{
封装字符串成对象
setValue(对象);
}
xml中
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="com.briup.ioc.proEdit.Address" value="com.briup.ioc.proEdit.AddressEditor" />
            </map>
        </property>
    </bean>
key=“无法识别的属性类型”
value="自定义属性编辑器"

 
[11]自定义事件
事件三要素:事件源   事件监听   事件处理
applicationContext类型对象
 1.在spring中我们可以自定义事件,并且可以使用
 ApplicationContext类型对象(就是spring容器container)来发布这个事件
 2.事件发布之后,所有的ApplicaitonListener(监听器)实例都会被触发
 3.并调用指定方法onApplicationEvent()来处理.

1)事件代码
public class rainEvent extends ApplicationEvent{
public RainEvent(Object source) {
            super(source);
        }
}
2)自定义事件监听器
public class RainListener1 implements ApplicationListener<RainEvent>{
        public void onApplicationEvent(RainEvent event) {
        //如果发现RainEvent事件发生,则自动调用监听器中当前方法
            System.out.println("唐僧大喊:" + event.getSource() + "赶快收衣服喽!");
        }

    }
3)在配置文件中配置监听器   让当前容器发布对应事件时调用
<bean class="com.briup.ioc.event.RainEventListener1"></bean>
4)test发布事件
container.publishEvent(new RainEvent("打雷了!下雨了"));
监听器监听实现对应的逻辑

[12]注解:ioc中的annotaion配置
@Autowired  只针对类类型  普通属性不能自动注入
1.xml文件中必须有 <context:annotation-config/>   告诉spring识别注解
2.注解可以放在成员变量  set方法  构造器上
3.默认按照byType方式匹配,如果不存在bean   会报异常
4.发现多个同类型  再byName
5. @Autowired可以结合@Qualifier("beanName")来使用  直接byName

@Resource  作用与@Autowired差不多
先byName再byType

@component 将类配置到容器中生成bean对象
1.直接定义bean,无需在xml中定义,两种同时存在,xml中的定义会覆盖类中注解的Bean定义
2.直接写在类上面
3.@Component使用之后需要在xml文件配置一个标签
<context:component-scan base-package="com.briup.ioc.annotation" />
表示spring检查指定包下的java类,看它们是否使用了 @Component注解
4.默认是单例  结合@Scope("prototype")变为非单例(xml中 scope="prototype")

spring
1.可以管理对象的生命周期
2.可以将对象和对象之间复杂的关联关系进行管理
 
补充:和@Component同样作用
@Controller  web
@Service    service
@Repository  dao







IOC:控制反转
         字面含义
         实现原理
          解决的问题
         配置方式


原文地址:https://www.cnblogs.com/yxj808/p/12023880.html