Spring

本文详细介绍了Spring框架的核心特性——控制反转(IOC)和面向切面编程(AOP)。通过实例展示了如何使用XML配置和注解实现Bean的管理,包括无参构造、有参构造以及各种依赖注入方式。此外,还探讨了Bean的作用域、生命周期以及不同类型的依赖注入。文章最后提到了Spring的快速入门步骤和配置文件的相关知识。
摘要由CSDN通过智能技术生成

SPRING

控制反转(IOC),面向切面编程(AOP)

组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZAPMsvkb-1636435587289)(Spring.assets/20170227200701831.gif)]

1、IOC理论推导

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ii94aYbB-1636435587293)(Spring.assets/1634883397649.png)]

在之前的业务中,用户需求可能会影响我们原来的代码,我们需要根据用户需求去修改源码!如果程序代码量十分大,修改一次的成本代价十分昂贵

我们使用一个set接口实现

public class UserServiceImpl implements UserService{
    private UserDao userDao;
    //利用set进行动态实现值的注入!
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void getUser() {
        userDao.getUser();
    }
}
  • 之前,程序是主动创建对象!控制权在程序员手上
  • 使用了set注入后,程序不在具有主动性,而是变成了被动的接受对象!
  • 这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了,系统的耦合性大大降低,可以更加专注的在业务的实现上!这是IOC的原型!

2、IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
上面的改法

在resources中创建beans.xml

<?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就是java对象 , 由Spring创建和管理-->
    <bean id="ud" class="com.leitao.dao.UserDaoImpl"/>
    <bean id="udmi" class="com.leitao.dao.UserMysqlImpl"/>
    <bean id="udoi" class="com.leitao.dao.UserDaoOracleImpl"/>

    <bean id="usi" class="com.leitao.service.UserServiceImpl">
        <property name="userDao" ref="ud"/>
     </bean>
</beans>

改的话直接改 ref 引用就行了

测试类MyTest

public class MyTest {
    public static void main(String[] args) {
        //用户调用的是业务层,dao层他们不需要接触!
        /*UserService userService = new UserServiceImpl();
        ((UserServiceImpl)userService).setUserDao(new UserMysqlImpl());
        userService.getUser();*/

        //获取ApplicationContext;拿到spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserServiceImpl usi = (UserServiceImpl) context.getBean("usi");
        usi.getUser();
    }
}

2、无参构造创建对象,默认

pojo里面User

public class User {
    private String name;

    public User() {
        System.out.println("User的无参构造");
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("show.......");
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

beans.xml

<bean id="user" class="com.leitao.pojo.User">
    <property name="name" value="张三"/>
</bean>

MyTest

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("user");
        user.show();
        System.out.println(user);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0KcKPCIb-1636435587294)(Spring.assets/1634897960574.png)]

3、有参构造创建对象

  • 下标赋值

    User里面创建有参构造方法

    beans.xml

    <!--第一种-->
    <bean id="user" class="com.leitao.pojo.User">
        <constructor-arg index="0"  value="雷涛学java"/>
    </bean>
    
  • 通过参数类型创建,如果参数有两个String就有问题(不推荐使用)

    <!--第二种-->
    <bean id="user" class="com.leitao.pojo.User">
        <constructor-arg type="java.lang.String" value="leitao"/>
    </bean>
    
  • 直接通过参数名(推荐)

    <!--第三种-->
    <bean id="user" class="com.leitao.pojo.User">
        <constructor-arg name="name" value="发射点发给大家喝咖啡的"/>
    </bean>
    

**总结:**在配置文件加载的时候,容器中管理的对象就已经初始化了!

4、spring配置

  • 别名
<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="bieming"/>
  • Bean配置
<!--name也是别名,可以取多个别名-->
<bean id="usert" class="com.leitao.pojo.UserT" name="t,u2,u3,u4">
    <property name="name" value="分公司看到了法国"/>
 </bean>
  • import

这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个

applicationContext.xml

<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>

到时候直接使用总配置文件

5、DI依赖注入

  • 构造器注入

    前面说过了

  • set方式注入【重点】

    • 依赖注入:Set注入
      • 依赖:Bean对象的创建依赖于容器
      • 注入:Bean对象
  • 拓展方式注入

1、spring 快速入门步骤

1、导入spring开发的基本包坐标

<!--导入坐标-->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>
    </dependencies>

2、编写Dao接口和实现类

UserDao

public interface UserDao {
    public void save();
}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("save running");
    }
}

3、创建spring核心配置文件

applicationContext.xml

<?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">
    
</beans>    

4、在spring配置文件中配置UserDaoImpl

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl"></bean>

5、使用spring的API获得Bean实例

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

2、spring配置文件

2.1Bean标签基本配置

用于配置对象交由spring来创建

默认情况下它调用的是类中的无参构造函数,如果没有则创建不成功

基本属性:

  • id:Bean实例在spring容器中的唯一标识
  • class:Bean的全限定名称
2.2Bean标签范围配置
scope:值对象的作用范围
  • singleton:默认值,单例的
    • Bean实例化个数:1个
    • Bean的实例化时机:当spring核心文件被加载时,实例化配置的Bean实例
    • Bean的生命周期:
      • 对象创建:当应用加载,创建容器时,对象就被创建了
      • 对象运行:只要容器在,对象一直活着
      • 对象销毁:当应用卸载,销毁容器,对象就被销毁

applicationContext.xml

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl" scope="singleton"></bean>

UserDaoDemo

ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
UserDao userDao2 = (UserDao) app.getBean("userDao");
System.out.println(userDao);
System.out.println(userDao2);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-daoqhghA-1636435587296)(Spring.assets/1634724076751.png)]

  • Prototype:多例的
    • Bean实例化个数:多个
    • Bean的实例化时机:当调用getBean()方法时,实例化配置的Bean实例
    • Bean的生命周期:
      • 对象创建:当使用对象时,创建新的对象实例
      • 对象运行:只要对象在使用中,就一直活着
      • 对象销毁:当对象长时间不用时,被java的垃圾回收机制回收
<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl" scope="prototype"></bean>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3VXLX61-1636435587298)(Spring.assets/1634724131852.png)]

  • request
  • session
  • global session
2.3Bean生命周期配置
  • init-method:指定类中的初始化方法名称
  • destroy-method:指定类中的销毁方法名称

applicationContext.xml

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>

UserDaoDemo

public class UserDaoDemo {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");
        System.out.println(userDao);
        app.close();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hOWEnjx6-1636435587300)(Spring.assets/1634726017646.png)]

2.4Bean实例化三种方式
  • 无参构造方法实例化
  • 工厂静态方法实例化

创建factory包里面StaticFatory

public class StaticFatory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

applicationContext.xml

<bean id="userDao" class="com.leitao.factory.StaticFatory" factory-method="getUserDao"></bean>

执行UserDaoDemo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y4yMvMkk-1636435587301)(Spring.assets/1634727894237.png)]

  • 工厂实例方法实例化

创建factory包里面DynamicFatory

public class DynamicFatory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

applicationContext.xml

<bean id="fatory" class="com.leitao.factory.DynamicFatory"></bean>
<bean id="userDao" factory-bean="fatory" factory-method="getUserDao"></bean>

执行UserDaoDemo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-moLTFf54-1636435587302)(Spring.assets/1634728674761.png)]

2.5Bean的依赖注入方式
  • set方法注入

  • (引用数据类型)

    UserServiceImpl

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void save() {
        userDao.save();
    }
}

applicationContext.xml

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.leitao.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
 </bean>

p命名空间注入

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl"></bean>
xmlns:p="http://www.springframework.org/schema/p"
<bean id="userService" class="com.leitao.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>

userController

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app =new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u3bfdGFb-1636435587303)(Spring.assets/1634781732339.png)]

  • 有参构造方式注入

UserServiceImpl

public class UserServiceImpl implements UserService {
    private UserDao userDao;

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

applicationContext.xml

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl"></bean>

<bean id="userService" class="com.leitao.service.impl.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

UserController和结果同上

2.6Bean的依赖注入的数据类型
  • 普通数据类型

    • set方式

    userDaoImpl

    private String username;
    private int age;
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public void save() {
        System.out.println(username+"+++++"+age);
        System.out.println("save running");
    }
    

    applicationCpntext.xml

    <bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl">
        <property name="username" value="张三"></property>
        <property name="age" value="18"></property>
    </bean>
    <bean id="userService" class="com.leitao.service.impl.UserServiceImpl">
            <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCtcDmpK-1636435587304)(Spring.assets/1634793706178.png)]

  • 引用数据类型

  • 集合数据类型

创建一个domain包里面User类

userImpl

private List<String> strList;
private Map<String, User> userMap;
private Properties properties;

public void setStrList(List<String> strList) {
    this.strList = strList;
}

public void setUserMap(Map<String, User> userMap) {
    this.userMap = userMap;
}

public void setProperties(Properties properties) {
    this.properties = properties;
}

System.out.println(strList);
        System.out.println(userMap);
        System.out.println(properties);

applicationContext.xml

<bean id="userDao" class="com.leitao.dao.impl.UserDaoImpl">
    <property name="strList">
        <list>
            <value>fdgfdg</value>
            <value>fdgs</value>
            <value>hfggfh</value>
            <value>gfhtydjryt</value>
        </list>
    </property>
    <property name="userMap">
        <map>
            <entry key="U1" value-ref="user1"></entry>
            <entry key="U2" value-ref="user2"></entry>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="p1">pppp1</prop>
            <prop key="p2">pppp2</prop>
            <prop key="p3">pppp3</prop>
        </props>
    </property>
</bean>

<bean id="user1" class="com.leitao.domain.User">
    <property name="name" value="李四"></property>
    <property name="addr" value="迁安"></property>
 </bean>
<bean id="user2" class="com.leitao.domain.User">
    <property name="name" value="路西"></property>
    <property name="addr" value="天津"></property>
</bean>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ww52eBbL-1636435587305)(Spring.assets/1634872142761.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值