Spring框架学习笔记1:IOC介绍和使用IOC注解的方式

什么是IOC

IOC(Inversion Of Control):控制反转。
其实指的是控制权力的反转。说白了,就是将原来通过new方式创建对象的权力交给spring,通过在配置文件中配置bean标签的形式创建对象,交由spring创建对象的过程。
然而实际上,凡是可以被称之为容器的,都具有IOC这种特性,比如tomcat容器,在使用的时候可以直接获取request和response对象。为了使spring更加完善,作者又提出了新的概念。
DI(Dependency Injection):依赖注入。
定义:为组件中需要的成员变量完成赋值的过程
1.组件对象中需要哪个组件,就将其声明为成员变量并提供公开的set方法。
2.在spring配置文件中使用在对应的标签内完成属性的赋值操作。

IOC总结:控制反转,将原来手动通过new关键字创建对象的权力交给spring,由spring工厂创建对象的过程。当然spring不仅要创建对象,还要在创建对象的同时,通过DI的方式维护组件和组件之间的调用关系。

DI基本语法
Dao层组件:

public class DeptDaoImpl implements  DeptDao{
    public void save(String name) {
        System.out.println("姓名:"+ name);
    }
}

Service层组件(调用了DAO层组件):

public class DeptServiceImpl implements DeptService {
    private DeptDao deptDao;

    public void setDeptDao(DeptDao deptDao) {
        this.deptDao = deptDao;
    }
    public void save(String name) {
        System.out.println("service name : "+ name);
        deptDao.save(name);
    }
}

spring.xml配置文件:

<bean class="di.DeptDaoImpl" id="aa"></bean>
<bean class="di.DeptServiceImpl" id="deptService">
        <!--
        property: 用来给组件中的属性进行赋值操作
        name:用来指定给组件中的哪个属性进行赋值(也就是变量名)
        ref: 用来指定对象在工厂中的唯一标识名(也就是bean的id)
        -->
        <property name="deptDao" ref="aa"></property>
    </bean>

测试:

public class test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        DeptServiceImpl deptServiceImpl = (DeptServiceImpl) context.getBean("deptService");
        deptServiceImpl.save("wuhaotian");

    }
}

DI中的注入方式

SET注入(了解语法,实际中用得少)

定义:就是使用成员变量set方法的方式进行注入;
set方式的注入语法:
1.八中基本类型+String类型+日期类型的注入,使用value属性进行赋值;

<property name="age" value="25"></property>

2.注入对象|组件类型,使用ref属性进行赋值;

<property name="deptDao" ref="aa"></property>

3.注入数组类型

	private String[] qqs;
    private DeptDao[] deptDaos;
    private Map<String,DeptDao> map;
    private Properties properties;

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

    public void setMap(Map<String, DeptDao> map) {
        this.map = map;
    }

    public void setDeptDaos(DeptDao[] deptDaos) {
        this.deptDaos = deptDaos;
    }

    public void setQqs(String[] qqs) {
        this.qqs = qqs;
    }

xml文件:

//注意这些都是在<bean>标签下面的东西
		<property ame="qqs">
        //数组使用array标签
            <array>
            //基本类型用value
                <value>a</value>
                <value>b</value>
                <value>c</value>
            </array>
        </property>
        <property name="deptDaos">
            <array>
            //引用类型用ref
                <ref bean="aa"></ref>
                <ref bean="aa"></ref>
                <ref bean="aa"></ref>
            </array>
        </property>
        <property name="map">
            <map>
            <!--基本类型和String直接用key,value,引用类型用key-ref,value-ref-->
                <entry key="first" value-ref="aa"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="driver">com.mysql.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:8080:/test</prop>
                <prop key="username">root</prop>
                <prop key="password">root</prop>
            </props>
        </property>

构造注入(了解语法,实际使用较少)

定义:就是使用类中的构造方法为类中的成员变量赋值的过程。
构造注入的语法:
1.需要哪个组件就将其声明为成员变量,并提供公开的构造方法。
2.在配置文件中对应的组件标签内部使用"< constructor-arg>"标签进行注入

 	private String name;
    private int age;
    private Date date;
    public EmpDAOImpl(String name, int age, Date date) {
        this.name = name;
        this.age = age;
        this.date = date;
    }

xml配置文件

//这里多个index,从0开始记录。其他的属性(基本类型,引用类型)用法和set注入是一样的
	<bean class="cdi.EmpDAOImpl" id="empDAO">
        <constructor-arg index="0" name="name" value="kid"></constructor-arg>
        <constructor-arg index="1" name="age" value="12"></constructor-arg>
        <constructor-arg index="2" name="date" value="2020/7/11"></constructor-arg>
    </bean>

自动注入

定义:就是通过在配置文件中完成类中属性的自动赋值。
注意:
1.底层使用的原理也是set注入的方式;
2.自动注入需要在对应组件标签上开启才能使用;
3.只能用于引用类型的注入,不能完成基本类型的注入;
4.注解用的是自动注入
5.自动注入在xml中看不出来组件之间的依赖关系
自动注入的语法:
1.需要哪个组件就将其声明为成员变量,并提供set方法;
2.在对应组件标签上加入autowired属性并指定自动注入的方式即可完成注入。

 private StudentDAO studentDAO;
    public void setStudentDAO(StudentDAO studentDAO) {
        this.studentDAO = studentDAO;
    }

    @Override
    public void save(String name) {
        System.out.println("Service DAO:"+name);
        studentDAO.save(name);
    }

xml文件

 <!--管理DAO组件-->
    <bean class="sdi.StudentDAOImpl" id="studentDAO"></bean>
    <!--
    autowire:用来给组件中成员变量完成自动赋值的操作
        byType:根据类型完成自动注入 根据成员变量类型去工厂找,找到对应类型完成赋值 找不到就不赋值
                注意:如果工厂中存在多个同一类型的组件,此方法会失效
        byName:根据名称完成自动注入 根据成员变量的名字去工厂找,找到对应类型完成赋值 找不到就不赋值
    -->
    <bean class="sdi.StudentServiceImpl" id="studentService" autowire="byType"></bean>

有关bean

bean的模式

  1. 工厂默认在管理对象时是使用单例模式,此时无论在工厂获取多少次始终是同一个对象;
  2. 如何修改成多例
<bean class=""  id="" scope="singleton|prototype(多例)">

spring构造对象原理

反射+构造方法

//工厂原理 反射+无参构造
testDAO td = (testDAO)Class.forName("绝对路径.testDAOImpl").newInstance();

bean生命周期

单例对象:工厂启动时,所有的单例对象随之创建;
工厂正常关闭时(调用context.close()方法),所有单例对象随之销毁;
多例对象:每次在工厂中使用时创建,而且多例对象一旦创建,就脱离了spring的管理,所以对象的销毁是jvm来进行管理。

注解介绍

@Component:组件,理论上可以在任意的类上进行添加,在扫描的时候都会完成bean的注册
@Controller:放置在控制层,用来接收用户的请求,
@Service:放置在业务逻辑层,
@Repository:仓库,放置在数据访问层
他们都可以完成bean注册功能,但是这些规定并不是spring识别的标识
在spring程序运行的过程中,不会对这四个注解做任何区分。都会完成bean的注册功能
在实际的开发过程中,最好能分清楚,以此提高代码的可读性。
在使用注解的时候,要告诉spring从哪个包开始扫描
需要导入context命名空间
在使用注解的时候没有定义id和class,那么是如何进行识别的呢
默认是把当前类的首字母小写之后进行识别的,如果需要改变名称,那么需要在注解后面添加value属性值来完成名字的修改

扫描路径参数

 <!--当定义好注解的扫描路径之后,可以做更细粒度的控制,可以选择扫描哪个注解,也可以选择不扫描哪个注解
        include-filter:表示要包含扫描的注解,一般不会定义此规则,但是如果引入的第三方包中包含注解,此时就需要使用此标签来进行标识。
        exclude-filter:表示要排除扫描的注解,使用较多
        参数:  
	        type:规则的类型
	        expression:表达式
        		参数:
		        assignable:可以指定对应的类的名称。但是表达式必须是完全限定名
		        annotation:按照注解来进行排除,但是表达式中必须是注解的完全限定名
		        regex:使用正则表达式的方式,一般不用
		        aspectj:使用切面的方式,一般不用
		        custom:使用自定义的方式,可以自己定义自己的筛选规则,一般不用

AutoWired装配方式

注意:当使用AutoWired注解的时候,自动装配的时候是根据类型实现的。
	  AutoWired是根据反射进行注入的。

​ 1、如果只找到一个,则直接进行赋值,

​ 2、如果没有找到,则直接抛出异常,

​ 3、如果找到多个,那么会按照变量名作为id继续匹配,


@AutoWired和@Resource的区别

 在使用自动装配的时候,出了可以使用@AutoWired注解之外,还可以使用@Resource注解,大家需要知道这两个注解的区别。
​ 1、@AutoWired:是spring中提供的注解,@Resource:是jdk中定义的注解,依靠的是java的标准
​ 2、@AutoWired默认是按照类型进行装配,默认情况下要求依赖的对象必须存在,@Resource默认是按照名字进行匹配的,同时可以指定name属性。
​ 3、@AutoWired只适合spring框架,而@Resource扩展性更好
 4、@Resource是按照名称进行装配的,而@AutoWired是按照类型进行装配的

泛型依赖注入

1、可以定义一个Base<T>类,在和Base相同的目录下定义具体的类,比如Student,Teacher,(注意:这里的Base类不要加自动注入的功能,否则可能会出错),然后根据具体传入的T,将对应的具体类型进行注入。

spring框架好处

  1. 使用配置文件管理java类,在生产环境中更换类的实现时不需要重新部署,修改文件即可;
  2. 默认使用单例模式,减少内存的占用;
  3. 通过依赖注入建立了类与类之间的关系,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值