04-Spring-IOC(DI)一

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linzhaoliangyan/article/details/88680014

* IOC&DI概述

 1 IOC (Inversion of Control),控制反转:生成对象的控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
 2 DI (Dependency Injection),依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依      赖关系注入到组件之中
 3 依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同
 4 依赖注入:
    是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源
 5 控制反转
    从容器的角度在描述,容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源

 6 好处是解耦

 * 自定义IOC框架
思考:能不能独立构造一个对象工厂,在对象创建工厂中建立好项目需要的对象?
好处:哪里需要对象,都是从对象工厂获取,方便集中地管理对象!!!

 * 前置知识:dom4j,反射,..

 * 前期准备

public class User implements Serializable {
    private int id;
    private String username;
    private String psw;
    private char sex;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public User(int id, String username, String psw, char sex) {
        this.id = id;
        this.username = username;
        this.psw = psw;
        this.sex = sex;
    }

    public User() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        User user = (User) o;
        return id == user.id &&
                sex == user.sex &&
                Objects.equals(username, user.username) &&
                Objects.equals(psw, user.psw);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, psw, sex);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", psw='" + psw + '\'' +
                ", sex=" + sex +
                '}';
    }
}


public interface UserDao {
    public void addUser(User user);
}


public class UserDaoImpl implements UserDao {
    @Override
    public void addUser(User user) {
        System.out.println("addUser");
    }
}


public interface UserService {
    public void reg(User user);
}

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void reg(User user) {
        userDao.addUser(user);
    }
}

* 添加dom4j的依赖
 <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
   </dependency>

* 编写BeanFactory
public class BeanFactory {
    /**
     * 存储对象
     * key:对象别名(其实就是id)
     * value:具体的对象
     */
    private static HashMap<String,Object> beans=new HashMap<String, Object>();

    public BeanFactory(String path){
        InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream(path);
        SAXReader reader=new SAXReader();
        try {
            Document doc = reader.read(is);
            // 获得根节点
            Element root = doc.getRootElement();
            // 获取所有bean节点
            List<Element> beanElements = root.elements();
            for (Element beanElement:beanElements){
                // 对象别名
                String id = beanElement.attributeValue("id");
                String className = beanElement.attributeValue("class");
                // 通过反射产生对象
                Object obj = Class.forName(className).newInstance();
                // 存放对象
                beans.put(id,obj);
            }
            // 处理:property 标签
            for (Element beanElement:beanElements){
                List<Element> propertyElements = beanElement.elements("property");
                if(propertyElements!=null){
                    // 处理多个properties标签
                    // 从容器获得当前的对象
                    Object obj = beans.get(beanElement.attributeValue("id"));
                    for(Element propertyElement:propertyElements){
                        String name = propertyElement.attributeValue("name");
                        String ref = propertyElement.attributeValue("ref");
                        // 从容器获取需要被赋值的对象
                        Object refObj = beans.get(ref);
                        // 获得当前的对象的setter方法并把需要被赋值的对象设置进去
                        // 构建setter的方法
                        // setUserDao
                        String setter="set"+name.substring(0,1).toUpperCase()+name.substring(1);
                        Method method = obj.getClass().getDeclaredMethod(setter, refObj.getClass().getInterfaces());
                       // 调用setter的方法
                        method.invoke(obj,refObj);
                    }
                }
            }
        } catch (DocumentException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过别名获取对象
     * @param name
     * @return
     */
    public Object getBeans(String name){
        return beans.get(name);
    }
}

<?xml version="1.0" encoding="utf-8"?>
<beans>
    <bean id="userDao" class="com.hx.hx02.dao.UserDaoImpl"></bean>

    <bean id="userService" class="com.hx.hx02.service.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

</beans>

 @Test
    public void test1(){
        // 获得UserServiceImpl的对象,通过BeanFactory
        BeanFactory factory=new BeanFactory("beans.xml");
        UserService userService = (UserService) factory.getBeans("userService");
        User user=new User();
        userService.reg(user);
    }

* 开发Spring IOC

        * 使用spring模式创建工程

   *   复制其他工程的User,UserDao,UserDaoImpl

public class App {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        UserDao userDao = (UserDao) context.getBean("userDao");
        User user=new User();
        userDao.addUser(user);
    }
}

<?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="userDao" class="com.hx.spring.dao.UserDaoImpl"></bean>
</beans>

 

  * Spring 常见jar介绍

Spring Aspects:Spring提供的对AspectJ框架的整合
Spring Beans:Spring IOC的基础实现,包含访问配置文件、创建和管理bean等。
Spring Context:在基础IOC功能上提供扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。
Spring Context Support:Spring context的扩展支持,用于MVC方面。
Spring Core:Spring的核心工具包
Spring expression:Spring表达式语言
Spring Framework Bom:
Spring Instrument:Spring对服务器的代理接口
Spring Instrument Tomcat:Spring对tomcat连接池的集成
Spring JDBC:对JDBC 的简单封装
Spring JMS:为简化jms api的使用而做的简单封装
Spring Messaging:是spring4.0为了集成jms发布的一个新模块,只有spring 4.0以后才支持
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框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。
Spring webmvc portlet:Spring MVC的增强

必须引入的5个jar文件:
commons-logging-xxx.jar   [日志处理]
spring-beans-xxx.RELEASE.jar  [读取bean节点]
spring-context-xxx.RELEASE.jar [spring上下文处理]
spring-core-xxx.RELEASE.jar  [spring核心功能]
spring-expression-xxx.RELEASE.jar  [spring表达式处理]

    * Spring maven 的构建方式

        * 创建普通的quickstart骨架的Java项目

        * 添加依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>

  * 在resources 目录下创建spring-config文件

 


<?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="userDao" class="com.hx.hx02.dao.UserDaoImpl"></bean>
</beans>


  @Test
    public void test1(){
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        UserDao userDao = (UserDao) context.getBean("userDao");
        User user=new User();
        userDao.addUser(user);
    }

 

   * SpringIOC的核心接口工厂

        * ApplicationContext

1 使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
2 该接口下有两个具体的实现类
    1) ClassPathXmlApplicationContext: 加载类路径下的Spring配置文件
    2) FileSystemXmlApplicationContext:加载本地磁盘下的Spring配置文件

  * BeanFactory(Spring 早期的形式)

  @Test
    public void test2() {
        BeanFactory beans = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        UserDao userDao = (UserDao) beans.getBean("userDao");
        User user=new User();
        userDao.addUser(user);
    }

   * BeanFactory和ApplicationContext的区别

 1 BeanFactory	:BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
 2 ApplicationContext :在加载spring-config.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能

* SpringIOC 创建对象方式

public class User implements Serializable {
    private int id;
    private String username;
    private String psw;
    private char sex;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public User(int id, String username, String psw, char sex) {
        System.out.println("User对象创建----有参数");
        this.id = id;
        this.username = username;
        this.psw = psw;
        this.sex = sex;
    }

    public User() {
        System.out.println("User对象创建----无参数");
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        User user = (User) o;
        return id == user.id &&
                sex == user.sex &&
                Objects.equals(username, user.username) &&
                Objects.equals(psw, user.psw);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, psw, sex);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", psw='" + psw + '\'' +
                ", sex=" + sex +
                '}';
    }
}

   * 无参数的构造方法

   * 有参数的构造方法       

<bean id="user" class="com.hx.hx02.bean.User">
        <constructor-arg name="id" type="int" value="10001"/>
        <constructor-arg name="username" type="java.lang.String" value="xiaohei"/>
        <constructor-arg name="psw" type="java.lang.String" value="123123"/>
        <constructor-arg name="sex" type="char" value="男"/>
    </bean>
 
 按照顺序可以不写
 <bean id="user" class="com.hx.hx02.bean.User">
        <constructor-arg  value="10001"/>
        <constructor-arg  value="xiaohei"/>
        <constructor-arg  value="123123"/>
        <constructor-arg  value="男"/>
 </bean>

 @Test
    public void test3() {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        User user = (User) context.getBean("user");
        System.out.println(user);
    }

* 工厂类的创建的方式        

public class UserFactory {
    public User getInstance(){
        return new User(10002,"小黑","123123",'男');
    }

    public static User getStaticInstance(){
        return new User(10002,"小黑","123123",'男');
    }
}

<bean id="factory" class="com.hx.hx02.bean.UserFactory"></bean>
    <bean id="user1" factory-bean="factory" factory-method="getInstance"/>

    <bean id="user2" class="com.hx.hx02.bean.UserFactory" factory-method="getStaticInstance"></bean>

@Test
    public void test4() {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        User user1 = (User) context.getBean("user1");
        User user2 = (User) context.getBean("user2");
        System.out.println(user1);
        System.out.println(user2);
    }

猜你喜欢

转载自blog.csdn.net/linzhaoliangyan/article/details/88680014
今日推荐