Spring学习第一步 配置环境

spring

spring配置:

  1. 创建spring工程

  2. 在pom.xml导入spring依赖和单元测试依赖

  3. 创建pojo包---> 在里面创建实体类

  4. 创建applicationContext配置文件 ---->写bean相关的id 和class

    id: 唯一标识符

    class:bean所对应的类型的具体包名

  5. 创建测试包test---->Test类

    1. 获取容器:ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

    2. //获取容器的对象bean 注意强制类型转换 直接在前面加上(强制类型转换符)

      Helloword helloword =(Helloword) applicationContext.getBean("helloSpring");

      1. 调用方法

        helloword.run();

    //一共改了几个点//1.setting 里maven 的配置 maven RUN里的编译
    //2.POM里的rescouce资源过滤(这个步骤可以没用什么时候target里面没有再加)
    //3.maven右侧test步骤的禁用,POM里打包方式为jar
    


根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象instanceof 指定的类型』
的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到l

1.两种属性赋值的方法:

<!-- 通过set方法注入的方式 -->

<!-- name: 属性-->

<!-- value:属性值-->

<!-- <property name="sex" value="男">-->

`

区别在于:

一个是通过sett方法赋值

一个是通过构造方法传参数

属性赋值:

  1. 字面值:通过value赋值

  2. 另一个类的类型:

    (1) ref="另一个类的 类型的bean的id"

(2)

(1ref="另一个类的 类型的bean的id"** (用的最多)

(2)二级联动方式:在第一个的基础上  

加上<property name=" 属性.属性" value= “属性值">

作用不大 只是修改了原来的属性值

注意:级联的方式,要保证提前为sClass属性赋值或者实例

<property name="sClass" ref="class">

</property><property name="sClass.classname" value="软件工程"></property>

<property name="sClass.classid" value="1"></property>
另一个类的id
/bean>
    <bean id="class" class="pojo.Class">
        <property name="classid" value="1"></property>
        <property name="classname" value="计算机科学与技术"></property>
        <property name="students" ref="student"></property>
    </bean>



(3)内部bean的方式


   <property name="sClass">
<!--        出bug:.NosuchBeanDefinitionException:-->
<!--        原因 这是内部bean 只能在bean 内部使用 不能被IOC 容器获取-->
        <bean id="class" class="pojo.Class">
            <property name="classid" value="2"></property>
            <property name="classname" value="计算机科学与技术"></property>
            <property name="students" ref="student">
            </property>
        </bean>
    </property>
给属性对象赋值小结:

用的最多是第一种和第三种方式

  1. 数组赋值

    在property 中添加 array标签
    1,字面值就用 value
    2.属性对象 用 ref
    
    
    <property name="a">
            <array>
            <value >1</value>
                <value >1</value>
                <value >2</value>
                <value >3</value>
                <value >4</value>
            </array>
        </property> 
    
  2. list集合赋值

注意事项:

获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named 'bookServiceImpl' available

属性赋值总结:

  1. 在bean里面都由

    中设置小标签

    数组用array

    List集合用 list

    set 集合用 set

    map集合用 entry 小标签 中key =” “ value=”“>

    properties 用 pro标签

    1664804191842


  
    <bean id="user" class="pojo.User">
        <property name="address" value="重庆市"> </property>
        <property name="age" value="29"></property>
        <property name="classes">
            <list>
               <null></null>
            </list>
        </property>
    <property name="hobby">
        <array>
            <value>唱个歌</value>
            <value>跳舞</value>
            <value>看书</value>
        </array>
    </property>
        <property name="gendes">
            <set>
                <value>qq</value>
                <value>123</value>
            </set>
        </property>
        <property name="maps">
            <map>
                <entry key="001" value-ref="student"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username"> 小王</prop>
                <prop key="password">123</prop>
                <prop key="url">3306@qq.com</prop>
            </props>
        </property>
    </bean>
</beans>






命名空间注入

p 命名空间注入: 通过属性

c命名空间注入 :通过构造器 const

注意:使用的时候要导入约束

1664867471858

bean作用域

bean作用范围:

默认score 是单例模式

工具类

1664867989274

自动装配:

1.autowire 属性

作用: 为类类型,接口类型赋值 就是省略了bean 标签中ref=" "

就不需要写 简单的< property 是ref=" ">

自动在容器中找到对应的bean类型的对象

bytype: 根据类型 确保class=" 全局唯一" . bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致

byName: 根据bean id 来配置 确保id 唯一 需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致

所谓的自动装配就是原来两行代码改成了autowire="byName"


l

<bean id="student" class="com.hqq.pojo.Student" p:sname="王新瑞" p:age="1" >
    <property name="cat" ref="cat"></property>
    <property name="dog" ref="dog"></property>
</bean>



autowire="byName"

2.标识为组件的

省略了原来

@autowired 通过byType的方式实现

@controller:

括号里面的表示自定义bean标签中 id  
@Controller("controller")
public class UserController {
}



1664970451529

小结:

Resource和@ Autowired 的区别:

·都是用来自动装配的,都可以放在属性字段上

。@Autowired 通过byType的方式实现,而且必须要求这个对象存在!【常用】

@Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】

·执行顺序不同:@Autowired通过byType的方式实现

1664958924158

1664883601024

注解开发

注意:使用注解开发要导入注解的支持:

在beans头部写以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       记得加入context 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
        这是扫描组件的包 最好写详细点 节约扫描时间
        <!--指定要扫描的包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.hqq.pojo"></context:component-scan>
 <context:annotation-config/>






扫描包

springmvc 负责控制层

spring 扫描全部的层次 就会出现重复扫描的情况

为了避免该情况

出现了

​```
exclude-filter: 除了某个文件
type: 
annotation 通过注解来进行排除(常用)
expression:需要复制排除注解的全类名




<context:component-scan base-package="com.hqq.pojo">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    
    
    
    
    
    
    
    

基于注解的自动装配

注解加扫描的方式

@Autowired:作用:为beam管理的成员变量赋值:

@Autowired:实现自动装配功能的注解

1,@Autowired注解能够标识的位置(用的最多)

  • α>标识在成员变量上,此时不需要设置成员变量的set方法* b>标识在set方法上

  • 标识在为当前成员变量赋值的有参构造上

2、@Autowired注解的原理

默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
*c>若byType和byName的方式都无妨实现自动装配,即IOC容器中有多个类型匹配的bean
且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionExceptiond>此时可以在要赋值的属性上,添加一个注解@QualifierI
*通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值

自动装配小结

  1. 对于简单的一些属性赋值 比如字面量 和类类型 接口类型赋值

  2. 通过扫描加注解的方式 就要记得在 bean 头文化加上

    注解 context 相关

       记得加入context 
           xmlns:context="http://www.springframework.org/schema/context"
    http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
            这是扫描组件的包 最好写详细点 节约扫描时间
            <!--指定要扫描的包,这个包下的注解就会生效-->
        <context:component-scan base-package="com.hqq.pojo"></context:component-scan>
     <context:annotation-config/>
    
    
    
    
  3. 组件相关

    @component 设置为组件

    @value 成员变量属性赋值

    @Autoried 给成员变量属性赋值 类似:ref 作用 通过byType方式

1664945478473

1664972510650

Java配置类

spring boot中用的比较多

1664886158899

1664886231557

设计模式

1664886446440

1664886572532

1664886587138

数据源jdbc.properties

1664889669852

写了jdbc.properties 以后:对比上下两幅图

1664889753015

测试类

1664889803496

三层架构

数据访问层(dao)

业务逻辑层(Service)

界面层(contraller) 大佬指挥别人做事 对外提供访问功能,只需要在测试类中创建界面层的对象

注意:

业务逻辑层的实现类中一定有数据访问层的对象

不管是xml 配置或者是注解配置 交给ioc容器管理的对象一定是实现类,而不是接口,因为实现类变化的快,而接口不会那么快

如何在界面层访问业务逻辑层: 在界面层创建业务逻辑层的对象,看上谁就去创建谁的对象

界面层一定有业务逻辑层的对象

靠对象之间相互关联

1664935087354

1664935543102

AOP


面向切面编程

公共的 通用的 重复的代码快 单独拿出来 ,在需要调用的方法中通过动态代理的方式进行

静态代理

1665838899881







/*
有接口和实现类时 先写接口
静态代理
一个接口
实现类和代理都要实现接口
实现类(目标对象)中实现具体业务功能
代理类中 :成员变量为接口类型 为了实现目标对象的灵活切换
在构造方法参数用成员变量写入 是为了实现目标对象和代理的联系
重写的接口中
1.实现切面功能
2.调用目标对象的方法
3.实现切面功能
测试类调用
注意:是调用代理类(括号里是目标对象的实例)
 */
 第三个版本:
 该静态方法实现了业务功能的灵活切换 
 未实现切面功能的灵活切换
 
  public void test2(){
        Service service = new Agent(new ProductService());
        service.buy();
        }
第四个版本的实现

缺点:没有实现业务的动态代理

优点 实现了切面的灵活切换

上接口就是上灵活

该思想最大的特点就是

提取接口出来

在一个实现类中和接口灵活连接是通过 成员变量的引入,而不是直接实现接口

通过构造方法实现目标对象的注入

jdk8之后有个接口默认实现

1665841055842


接口默认实现 :加了大括号,表示方法的空实现 做到不用实现全部方法,想实现那个接口就实现那个接口
 defalt 返回值 方法名() { }
 */
public interface Aop {
    default void before(){}
   default void after(){ }
    default void exception(){}
}



测试类:
public void test3(){
        Service service = (Service) new com.test4.service.Agent(new com.test4.service.BookService(),new TranctionAop());
        
        
        Service service1 = new Agent(service,new RiziAop());
        这行代码实现了切面功能的添加  不断累加切面功能 即实现日志功能又实现事务功能
         service1.buy();

    }
}
posted @ 2022-10-03 17:54  GoblinQ  阅读(89)  评论(0编辑  收藏  举报
复制代码