2021-10-29静态方法如何使用,多种配装的使用,多种注解的使用,完全注解的详解

本文详细介绍了Spring的IoC容器及其创建对象的三种方式:无参构造器、有参构造器和工厂方法。重点讲解了静态工厂创建对象的使用,以及通过set方法进行依赖注入的简化方式——p名称空间。此外,还讨论了自动装配的两种方式:按名称和按类型,并指出其可能带来的问题。最后,提到了注解在简化配置和管理对象依赖关系上的优势,并给出了注解配置的例子。
摘要由CSDN通过智能技术生成

Spring的Ioc容器


是Spring核心内容,
作用:创建对象&处理对象的依赖关系
Ioc容器创建对象有几种方式;
1) 调用无参构造器
2) 调用有参构造器
3) 工厂创建对象:
实例工厂类,非静态方法(实例方法)创建对象,
静态工厂类,静态方法创建对象

非静态方法(实例方法)创建对象

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
新建一个User实体,通过工厂进行调用,再使用TestBean04进行测试,在applictionContext中插入
在这里插入图片描述
看到已经报红色的错误,点开看一下,是因为没有赋值,
在这里插入图片描述
这时候就已经可以通过工厂获取对象了/

静态方法如何调用

有两种调用方式:
1、通过类名.静态方法名()调用。推荐
2、通过类的实例对象.静态方法名
在这里插入图片描述

使用静态工厂创建对象

在applictionContext.xml中中的class指定的就是工厂类型,factory-method 是工厂中的静态方法
静态工厂不需要对象来调用,可以直接调用类来使用
在这里插入图片描述
从applictionContext.xml中可以看出,静态工厂通过class直接调用了类,并没有调用对象再调用类
在这里插入图片描述

对象依赖关系,set注入简写

spring中,如何给指定对象的属性赋值,DI,依赖注入
5.2.2 通过set方法给属性注入值(昨天已经讲过)
5.2.3 p名称空间(了解)
5.2.4 自动装配(了解)
5.2.5 注解(掌握)
我们昨天讲过的set注入,今天的p名称空间和set注入差不多,就是set注入的简写
Spring的p标签是基于XML Schema的配置方式,目的是为了简化配置方式。由于Spring的p标签是spring内置的,只要在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"
       xmlns:util="http://www.springframework.org/schema/util"
       
       xmlns:p="http://www.springframework.org/schema/p"
       
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-5.0.xsd">

在这里插入图片描述
在这里插入图片描述
可以看出,简写的p其实和原来的用途一样,只是所需写的代码变得更加简洁

PS:不能同时将p名称空间写了之后,再写详细的,否则会报错。只能写一个
在这里插入图片描述

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Property 'age' is already defined using both <property> and inline syntax. Only one approach may be used per property.
Offending resource: class path resource [applicationContext.xml]

在这里插入图片描述

自动装配


根据名称自动装配:autowire=“byName”
Spring会自动去IoC容器中找与属性名同名的引用的对象,并自动注入。

<?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:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-5.0.xsd">

    <!-- ###############自动装配############### -->

    <bean id="userDao" class="org.jabari.spring.core.beans.auto.UserDao"></bean>


    <bean id="userService" class="org.jabari.spring.core.beans.auto.UserService" autowire="byName">
        <!--<property name="userDao" ref="userDao"/>-->
    </bean>
    <!-- 根据“名称”自动装配: ucDog注入的属性,会去IoC容器中自动查找与属性同名的对象 -->
    <bean id="ucDog"
          class="org.jabari.spring.core.beans.auto.UserController" autowire="byName"></bean>

控制器UserControllerJava代码如下:
package org.jabari.spring.core.beans.auto;

import javafx.application.Application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserController {

    private UserService userService ; // null , = new UserService()

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    void doGet() {
        System.out.println("----UserController.doGet():");
        userService.addUser("张三"); // java.lang.NullPointerException
        // ................
    }


    public static void main(String[] args) {
        // 手动new的方式来创建对象。
        UserController uc = new UserController();
        UserService ser = new UserService();
        uc.setUserService(ser);
        UserDao ud = new UserDao();
        ser.setUserDao(ud);

        // 交给Spring的IoC容器类给我们创建对象,管理注入对象依赖关系。
        /*ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");

        UserController uc = context.getBean("ucDog", UserController.class);*/

        uc.doGet();
    }
}

服务层UserServiceJava代码如下:
package org.jabari.spring.core.beans.auto;

public class UserService {

    private UserDao userDao;  // null ,     = new UserDao()

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

    public void addUser(String name) {
        System.out.println("----UserService.addUser():");
        userDao.insertUser(name);
    }
}


持久层UserDaoJava代码如下:
package org.jabari.spring.core.beans.auto;

public class UserDao {

    int insertUser(String name){
        // JDBC:数据库新增用户
        System.out.println("----UserDao.insertUser():");
        return 0;
    }
}

全局自动装配

也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”。在元素的属性中加入:default-autowire=“byName” 就可以实现根据名称自动装配了。

<?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:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-5.0.xsd" default-autowire="byName">

    <!-- ###############自动装配############### -->

    <bean id="userDao" class="org.jabari.spring.core.beans.auto.UserDao"></bean>


    <bean id="userService" class="org.jabari.spring.core.beans.auto.UserService" >
    </bean>

    <bean id="ucDog"
          class="org.jabari.spring.core.beans.auto.UserController" ></bean>


</beans>

类型自动装配

根据类型自动装配:autowire=“byType”
必须确保该类型在IoC容器中只有一个对象,否则报错!

<?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:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-5.0.xsd"
       default-autowire="byType">

    <!-- ###############自动装配 , 根据类型自动装配 ############### -->

    <bean id="userDao1" class="org.jabari.spring.core.beans.auto.UserDao"></bean>


    <bean id="userService2" class="org.jabari.spring.core.beans.auto.UserService" >
    </bean>

    <!--
         此处再创建一个UserService类型的Bean对象的话,就会报错,IoC容器中自动根据类型匹配,必须要求此类型的对象唯一。
        因为,在UserController的 userService的属性的类型时UserService,但是再IoC容器种,上面已经创建了
        一个UserService类型的对象,对象名叫:userService2。
       -->
    <!--<bean id="userService3" class="org.jabari.spring.core.beans.auto.UserService" >
    </bean>-->

    <!--p:userService-ref="userService3"-->
    <bean id="ucDog"
          class="org.jabari.spring.core.beans.auto.UserController" ></bean>


</beans>

Spring提供的自动装配主要是为了简化配置; 但是不利于后期的维护。
(一般不推荐使用)

注解

注解方式可以简化spring的IoC容器的配置!

使用注解步骤:
1)先引入context名称空间
xmlns:context=“http://www.springframework.org/schema/context”
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
在这里插入图片描述

2)开启注解扫描
<context:component-scan base-package=“org.jabari.spring.user”></context:component-scan>
在这里插入图片描述
会自动扫描org.jabari.springg.core.auto包下类的注解

3)使用注解
通过注解的方式,把对象加入IoC容器。

   创建对象以及处理对象依赖关系,相关的注解:
	@Component   

作用:指定把一个对象加入IoC容器
[注]:
1.如果component注解后面什么都不加,
默认的value值就是类名(其中首字母小写)。
2.该注解只能加在类(class)或者接口(interface)上。

@Repository 作用同@Component; 在持久层使用
@Service 作用同@Component; 在业务逻辑层使用
@Controller 作用同@Component; 在控制层使用

@Resource 属性注入
属性注入:还可以用:@Autowired
在这里插入图片描述

在这里插入图片描述

总结:
1) 使用注解,可以简化配置,且可以把对象加入IoC容器,及处理依赖关系(DI)
2) 注解可以和XML配置一起使用。

Spring注解补充

1、1什么是注解?
注解是代码的特殊标记
注解的格式:@注解名称(属性名称=属性值,属性名称=属性值)
可以使用的地方:可以作用在类上面、方法上面、属性上面
使用注解的目的:简化配置.xml的代码

1、2 Spring的Bean管理中创建对象提供的 注解
@Component、@Controller、@Serveic、@Repository

1、3在xml配置文件中开启组件扫描
如果扫描多个包,多个包用逗号隔开,或者直接扫描它们共同的上层目录。

		<context:component-scan base-package="org.jabari.spring.user"></context:component-scan>

补充说明:
组件扫描的细节配置,不允许扫描包的配置

<!--不能搜索到service包下的@Controller注解的类-->
    <context:component-scan base-package="service">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

	
<!--use-default-filters的默认值为true,即扫描整个包;设置为false则是代表不扫描整个包-->
    <context:component-scan base-package="service" use-default-filters="false">
    <!--只能搜索到service包下的@Controller注解的类-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

Spring完全注解开发


1、创建配置类,替代xml文件

//作为配置类,替代xml配置文件
@Configuration 
//代表需要扫描的包
@ComponentScan(basePackages =
        {"com.neu.eshop.dao","com.neu.eshop.service"})
public class SpringConfig {
  
}

2、创建UserDaolmpl类


@Repository(value = "user")
//上面的相当于
//@Repository:new UserDaoImpl();
//Value = “user”:UserDaoImpl user = new UserDaoImpl();

public class UserDaoImpl {
    public void print() {
        System.out.println("dao add......");
    }
}

3、创建UserServiceImpl类

@Component(value = "userService")
public class UserServiceImpl {

    @Value(value = "abc")
    private String name;

   //@Autowired单独使用效果相同
    @Autowired
    @Qualifier(value = "user")
    private UserDaoImpl userDao;

    public void add(){
        System.out.println("service add.......");
        userDao.print();
        System.out.println(name);
    }
}

4、测试基于注解方式的开发

public class TestService {

    /**
     * 基于xml和注解方式管理bean
     *  ClassPathXmlApplicationContext
     */
    @Test
    public void test(){
       
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService service = context.getBean("userService", UserService.class);
        service.add();
    }


    /**
     * 完全基于注解方式管理Bean
     * AnnotationConfigApplicationContext完全注解方式上下文
     */
    @Test
    public void testAdd(){
        //与xml配置文件使用的不同点,实现类的使用不同
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserServiceImpl service = context.getBean("userService", UserServiceImpl.class);
        service.add();
    }

}

测试结果:

service add…
dao add…
abc

在这里插入图片描述
相当于:
@Repository:new UserDaoImpl();
Value = “user”:UserDaoImpl user = new UserDaoImpl();

在这里插入图片描述
相当于:
@Autowired:要求SpringIoC容器给我们自动装配一个UserDaoImpl类型的对象。
@Qualifier(value = “user”):要求指定UserDaoImpl类型的对象名称:user。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值