Spring:配置,强耦合,IOC反转,三种注入

Spring:对bean的一种封装,以后拿对象不要new了。Spring是一个项目管理框架,同时也是一套Java EE解决方案。
核心模块主要包括:IOC,AOP,事物的统一管理三方面

spring 的使用方法;

1,首先要会搭建一个工厂;
工厂就是生产类的所以先定义一些类。可以在类里面定义一些方法,
2,配置依赖;
这一个依赖包含spring所有的依赖,maven的依赖具有传递性。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qf</groupId>
    <artifactId>spring1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!-- Spring常用依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <!--        main方法的测试包就不要写main方法了-->
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!-- 生命周期 -->
            <!--        测试出结果为了不占用资源就不用test,不想要的测试就不要写test-->
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3,配置spring-config.xml文件;
定义要生产的对象。
标签遵循Schema规范才能被解析。

<?xml version="1.0" encoding="UTF-8"?>
<!--beans是根标签,用来声明这是一个装很多bean的容器
    xmlns语义化标签所在的命名空间,就是定义改文件中标签的含义
    xmlns:xsi:XMLSchema-instance 标签遵循Schema标签标准。
    xsi:schemaLocation:xsd文件位置,用以描述标签语义、属性、取值范围等。
    -->
<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.qf.dao.UserDAOImpl"></bean>
    <bean id="userService" class="com.qf.service.UserServiceImpl"></bean>
   <!-- bean:代表一个对象;
    id:唯一标识符(相当于键)
    class:表示给对象所属类的全限路径名=包名+类名-->

</beans>

4,写测试类;
根据ApplicationContext启动工厂,然后通过bean获取对象。

public class SpringFactory {
    @Test
    public void testSpringFactory(){
        //启动工厂(从xml里面拿id)
       ApplicationContext context = new ClassPathXmlApplicationContext("/spring-config.xml");
    //获取对象
        UserDAO userDAO = (UserDAO) context.getBean("userDAO");//一定要向下专型
        UserService userService = (UserService) context.getBean("userService");

        userDAO.delereUser(1);//
        userService.delereUser(2);
    }
}

IOC(Inversion of Control )控制反转(十分重要:主要吧dao,service,等方法类放到IOC,model和util等不要放进去仓库)
含义:原来我们需要对象,我们都是自己手动的去new对象(控制权在使用者手里)
作用:ioc:将对象放到一个容器中,谁想用,则容器主动的将对象分配给他(对象的控制权将会反转给容器。
反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)
解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健

控制反转只是思想层面的理解,要想完成反转就要靠一次又一次的DI(依赖注入)

项目中强耦合问题
所谓的强耦合就是serviceimpl和daoimpl的绑定关系,在我们实现逻辑类serviceimpl时,必须要绑定对相应的接口类dao实现对应的daoimpl,每次要想实现不同的daoimpl的就必须修改对应的serviceimpl,这样在做大型项目时就浪费了大量的资源,增加维护成本,解决思路是修改一个对应的不需要改变。所有通过在实现里定义一个接口,加一个get、set方法用以去获取要实现的方法。代码如下:
1,强耦合现象

public class UserDAOImpl implements UserDAO{....}

public class UserServiceImpl implements UserService {
    // !!!强耦合了UserDAOImpl!!!,使得UserServiceImpl变得不稳健!!
    private UserDAO userDAO= new UserDAOImpl();
    @Override
    public User queryUser() {
        return userDAO.queryUser();
    }
    ....
}

2,解决办法

// 不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)
public class UserServiceImpl implements UserService {
    // !!!不再耦合任何DAO实现!!!,消除不稳健因素!!
    private UserDAO userDAO;
    // 为userDAO定义set/get,允许userDAO属性接收spring赋值
    //Getters And Setters
    @Override
    public User queryUser() {
        return userDAO.queryUser();
    }
        public UserDAO getUserDAO() {
        return userDAO;
    }
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
    ....
}

config。xml中也要加上dao的属性名(通过get/set方法去得到值)
在这里插入图片描述
DI(Dependency Injection)依赖注入
概念:在Spring创建对象的同时,为其属性赋值,称之为依赖注入。

1,set注入;原理就是调用set方法实现的;
分为:集合,自建属性,map集合
(看有没有赛进去值可以在test里加sout加断点,控制台查看)

<?xml version="1.0" encoding="UTF-8"?>
<!--beans是跟标签,用来声明这是一个装很多bean的容器
    xmlns语义化标签所在的命名空间,就是定义改文件中标签的含义
    xmlns:xsi:XMLSchema-instance 标签遵循Schema标签标准。不同的标签决定不同的作用
    xsi:schemaLocation:xsd文件位置,用以描述标签语义、属性、取值范围等。
    -->
<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:唯一标识符(相当于键)
       class:表示给对象所属类的全限路径名=包名+类名-->



    <!--bean定义要工厂生产的对象-->
    <bean id="userDAO" class="com.qf.dao.UserDAOImpl"></bean>
<!--    想要Mydao运作只要改一下id和对应的ref(只修改了新加的类和工厂的配置)-->
    <bean id="userDAO2" class="com.qf.dao.MyUserDao"></bean>
    <bean id="userService" class="com.qf.service.UserServiceImpl">
        <!--如何给bean的属性赋值?
        方法1:通过构造方法(constructor-arg标签)
        name:构造方法的形参名(也就是set的形参)
        value:给简单类型赋值(八大基本数据和String)
        ref:给引用数据类型赋值,引用数据类型就是对象,由于只要是对象就交给容器控制
            所以ref就是该对象在容器的id
            如果引用数据类型是容器(list,map,set)

        方法2set注入(property标签)
        name:形参名
        value:给简单类型赋值(八大基本数据和String)日期用'/'
        bean:直接给应用数据类型赋值-->

        <property name="userDAO" ref="userDAO2"/>
<!--        为userDAO的属性赋值(所以要有getset方法),值是id为userDAO的一个bean就是指 <bean id="userDAO" -->
    </bean>


<!--自建属性:一定先bean出一个工厂对象才能注入user里-->
<bean id="addr" class="com.qf.entity.Address">
    <property name="id" value="1"/>
    <property name="city" value="bj"/>
</bean>


<!--    set注入(为user的属性赋值,===所以要有set方法用于注入时调用)-->
    <bean id="user" class="com.qf.entity.User">
        <property name="id" value="10"/>
        <property name="password" value="123456"/>
        <property name="sex" value="male"/>
        <property name="age" value="19"/>
        <property name="bornDate" value="2020/12/12"/>
<!--        数组-->
        <property name="hobbys">
            <array>
                <value>football</value>
                <value>basketball</value>
            </array>
        </property>
<!--        结合-->
        <property name="names">
            <list>
                <value>tom</value>
                <value>jack</value>
            </list>
        </property>
<!--        set集合-->
        <property name="phones">
            <set>
                <value>1725648463</value>
                <value>1736484737</value>
            </set>
        </property>
<!--        map集**-->
        <property name="countries">
            <map>
                <entry key="zh" value="chaina"></entry>
                <entry key="en" value="english"></entry>
            </map>
        </property>

<!--        文件注入-->
        <property name="files">
            <props>
                <prop key="url">jdbc:mysql:111</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
<!--        自建属性:相当于引用数据类型;当对象处理-->
        <property name="address" ref="addr"></property>
    </bean>


</beans>

2,构造注入
就是调用构造方法
必须是有参

<!--    构造注入 (就是走构造方法)-->
<bean id="student" class="com.qf.entity.Student">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="wjl"/>
    <constructor-arg name="sex" value="male"/>
    <constructor-arg name="age" value="19"/>
</bean>

3,自动注入(了解)
不用在配置中 指定为哪个属性赋值,及赋什么值.
由spring自动根据某个 “原则” ,在工厂中查找一个bean,为属性注入属性值。

<bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" />
<!-- 为UserServiceImpl中的属性基于类型自动注入值 -->
<bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byType"></bean>
<bean id="userDao" class="com.qf.spring.part1.injection.UserDaoImpl" />
<!-- 为UserServiceImpl中的属性基于类型自动注入值 -->
<bean id="userService" class="com.qf.spring.part1.injection.UserServiceImpl" autowire="byName"></bean>

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值