Spring随笔(IOC/DI 及注入方式)

为什么要使用Spring,优点是什么?

1.高内聚低耦合,简化开发
spring是一个大工厂(容器),可以将对象的创建和依赖关系的维护全部交给spring管理。
2.支持Aop编程
方便对程序的权限拦截和运行性能进行监控
3.声明式事务支持
通过过配置就可以完成对事务的管理,无需手动编程
4.支持Junit
5.方便集成各种优秀的框架

核心技术

IOC:控制反转

什么是控制反转?Ioc不是一种技术而是一种设计思想,传统的开发中我们在对象的内部通过new直接创建对象,是程序主动创建依赖对象。IOC意味着我们将对象的控制权交给专门容器去管理。这样就降低了程序的耦合性。控制是什么?主要就是控制了外部资源获取。反转:传统的方式是我们在自己在对象中主动控制直接获取依赖对象,就是正转。而反转则是由容器来帮助我们创建对象和注入依赖对象。对象只是被动的接受依赖对象。也就是说依赖对象的获取被反转了。

简单的说就是A类要使用B接口中的方法 我们传统的做法就是在A类中直接new一个B接口的实现类对象。但是显然这样做类和接口的依赖太强了。IOC是将A类B接口和他的实现类交给IOC容器,通过IOC容器的配置来实现他们之间的关联。

DI:依赖注入

DI是什么?IOC和DI是同一概念的不同描述。

DI的三种方式

测试类

package com.spring.demo;

public class BookServiceImpl implements BookService {


    @Override
    public void insert() {
        System.out.println("调用dao");


    }

}
package com.spring.demo;

public class BookDaoImpl implements BookDao {

    @Override
    public void insert() {
        System.out.println("插入数据");

    }

}
  • 构造器注入
package com.spring.demo;

public class BookServiceImpl implements BookService {
//传统方式  BookDao b=new BookDaoImpl();
    private BookDao bookdao;
//构造函数
    public BookServiceImpl(BookDao bookdao) {

        this.bookdao = bookdao;
    }

    @Override
    public void insert() {
        System.out.println("调用dao");
        bookdao.insert();

    }

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
         ">
    <bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
    <bean id="Service" class="com.spring.demo.BookServiceImpl">
    <!-- 构造默认从零开始 -->
        <constructor-arg index="0" ref="Dao">
        </constructor-arg>
    </bean>
</beans>
  • set方法注入(属性注入)
public class BookServiceImpl implements BookService {
    // 之前的方式 BookDao dao=new BookDaoImpl(); 耦合性强
    private BookDao bookDao;
// set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void insert() {
        System.out.println("调用dao");
        this.bookDao.insert();
    }

}

BooKDao省略

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- bean definitions here -->
    <!-- Ioc 控制反转 ,创建service实例 -->
    <bean id="BookService" class="BookServiceImpl">
        <!-- service依赖于Dao 注入 name bean的属性名 ref 注入的bean的id -->
        <property name="bookDao" ref="BookDao"></property>
    </bean>
    <!-- Ioc 创建BookDao实例 -->
    <bean id="BookDao" class="BookDaoImpl"></bean>
    </beans>

注意的是:假如我们要注入一个简单javaBean对象,他没有无参的构造方法是无法使用属性注入的

package com.spring.demo;

public class User {
    private String name;
    private Integer age;

    public User(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

如果此时我们不指定构造的参数 会报一个错误:
这里写图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
         ">
     <!-- type参数返回值类型  index 参数位置 -->    
    <bean id="user" class="com.spring.demo.User">
        <constructor-arg type="java.lang.String" index="0"
            value="花花"></constructor-arg>
        <constructor-arg type="java.lang.Integer" index="1"
            value="10"></constructor-arg>
    </bean>


    <bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
    <bean id="Service" class="com.spring.demo.BookServiceImpl">
        <property name="user" ref="user"></property>
        <!-- 构造默认从零开始 -->
        <constructor-arg  ref="Dao">

        </constructor-arg>
    </bean>
</beans>

所以我们在开发中要保留默认构造,使用属性注入使用< proprety>标签 使用构造注入使用的是< constructor-arg>标签

  • 接口注入(基本不用)

    反射获取实例化对象

  • 注解注入
    使用注解注入首先要引入标签和命名空间。
    @Component取代了标签
    @Component取代了
    web开发提供了三个衍生注解
    @Repository dao层
    @Service service 层
    @Contorller web层
    普通值 @Value()
    引用值 :
    按照类型注入
    @Autowired
    按照名称注入
    1 .@Autowired
    @Qualifier(“名称”)
    2.@Resource(“名称”)

    生命周期:
    初始化:@PostConstruct
    销毁: @PreDestory
    作用域:@Scope(“prototype”)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
    <!-- 扫描组件 -->
    <context:component-scan base-package="com.spring.annotation"></context:component-scan>
</beans>
package com.spring.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller("BookActionid")
public class BookAction {
    //按类型注入
    @Autowired
    private BookService bookService; 

    public void insert() {
        System.out.println("这是web");
        bookService.insert();

    }

}
package com.spring.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl implements BookService {

    private BookDao bookdao;
    //按名称注入
    @Autowired
    @Qualifier("BookDaoImpl")
    public void setBookdao(BookDao bookdao) {
        this.bookdao = bookdao;
    }

    @Override
    public void insert() {
        System.out.println("调用dao");
        bookdao.insert();

    }

}
package com.spring.annotation;

import org.springframework.stereotype.Repository;

@Repository("BookDaoImpl")
public class BookDaoImpl implements BookDao {

    @Override
    public void insert() {
        System.out.println("插入数据");


    }

}
  • 静态工厂注入
    常用于整合其他框架 ,静态工厂所有方法必须是static的
package com.spring.staticFactory;

public class BookServiceImpl implements BookService {
    @Override
    public void insert() {
        System.out.println("静态工厂实例化");
    }
}
package com.spring.staticFactory;

public class MyBeanFactory {

    public static BookService getServiceInstance() {
        return new BookServiceImpl();

    }

}
<!-- facory-method 静态方法名称 -->
    <bean id="BookService" class="com.spring.staticFactory.MyBeanFactory"
        factory-method="getServiceInstance"></bean
  • 实例工厂注入
    实例工厂所有的方法都是非静态的
package com.spring.InstanFactory;

public class MyBeanFactory {
    public BookService getServiceInstance() {
        return new BookServiceImpl();

    }

}
<!-- 创建工厂实例 factory-bean 确定工厂实例 factory-method 确定普通方法 -->
    <bean id="MyBeanFactory" class="com.spring.InstanFactory.MyBeanFactory"></bean>
    <bean id="BookService" factory-bean="MyBeanFactory"
        factory-method="getServiceInstance"></bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章