spring笔记

spring配置

别名

    <bean id="user" class="com.zeng.pojo.User">
        <property name="name" value="AAAAAA"/>
    </bean>
    <!--别名-->
    <alias name="user" alias="ladjfa"/>

Bean配置

    <!--
        id:bean的唯一标识符,相当于对象名
        calss:bean对象所对应的全限定名:包名+类型
        name:也是别名,而且name可以同时取多个别名
    -->
    <bean id="user" class="com.zeng.pojo.User" name="user2 user5,user3;user4">
        <property name="name" value="AAAAAA"/>
    </bean>

import

可以将多个配置文件,导入合并成一个

    <import resource="beans.xml"/>

依赖注入

构造器注入

Set方式注入

  • 依赖注入:Set注入!
    依赖:bean对象的创建依赖于容器
    注入:bean对象中的属性,由容器注入
<bean id="address" class="com.zeng.pojo.Address">
        <property name="address" value="中国湖北襄阳"/>
    </bean>
    <bean id="student" class="com.zeng.pojo.Student">
        <!--第一种,普通值注入,value-->
        <property name="name" value="abc"/>
        <!--第二种,Bean注入,ref-->
        <property name="address" ref="address"/>
        <!--数组-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>三国演义</value>
                <value>水浒传</value>
                <value>西游记</value>
            </array>
        </property>
        <!--list-->
        <property name="hobbys">
            <list>
                <value>抽烟</value>
                <value>喝酒</value>
                <value>烫头</value>
            </list>
        </property>
        <!--map-->
        <property name="card">
            <map>
                <entry key="身份证" value="1233211"/>
                <entry key="银行卡" value="001233211"/>
            </map>
        </property>
        <!--set-->
        <property name="games">
            <set>
                <value>nba2k</value>
                <value>lol</value>
            </set>
        </property>
        <!--null-->
        <property name="wife">
            <null/>
        </property>
        <!--配置文件类型-->
        <property name="prop">
            <props>
                <prop key="driver">22355@ss</prop>
                <prop key="url">www.baidu.com</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>

拓展方式注入

可以使用c和p命名空间进行注入

    <!--p命名空间注入,可以直接注入属性的值:property-->
    <bean id="user" class="com.zeng.pojo.User" p:name="小小飞" p:age="23" />
    <!--c命名空间注入,通过构造器注入:construct-args-->
    <bean id="user2" class="com.zeng.pojo.User" c:name="大大飞" c:age="22" />

测试

    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
//        User bean = context.getBean(User.class);
        User user = context.getBean("user",User.class);
        User user1 = context.getBean("user2",User.class);
        System.out.println(user.toString());
        System.out.println(user1.toString());
    }

注意点:c和p命名空间不能直接使用,需要导入xml约束

       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"

Bean作用域

在这里插入图片描述

  1. 单例模式(spring默认机制):scope="singleton"
    <bean id="user2" class="com.zeng.pojo.User" c:name="大大飞" c:age="22" scope="singleton"/>
  1. 原型模式:每次从容器中get对象的时候,都会产生一个新的对象:scope="prototype"
    <bean id="user2" class="com.zeng.pojo.User" c:name="大大飞" c:age="22" scope="prototype"/>

Bean的自动装配

  • 自动装配是Spring满足Bean依赖的一种方式!
  • Spring会在上下文中自动寻找,并自动给bean装配属性!
    在spring中有三种装配方式:
  1. 在xml中显示的配置
  2. 在java中显示配置
  3. 隐式的自动装配bean

byName自动装配

    <!--
    byName:会自动在容器上下文中查找和自己对象set方法后面值对应的beanid
    -->
    <bean id="people" class="com.zeng.pojo.People" autowire="byName">
        <property name="name" value="小小飞"/>
    </bean>

byType自动装配

    <!--
    byType:会自动在容器上下文中查找和自己对象属性类型相同的bean!
    -->
    <bean id="people" class="com.zeng.pojo.People" autowire="byType">
        <property name="name" value="小小飞"/>
    </bean>

小结:

  • byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!

使用注解实现自动装配

要使用注解需修改配置:

  1. 导入约束:context约束
  2. 配置注解的支持: context:annotation-config/
<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd“>

    <context:annotation-config/>

</beans>

@Autowired
直接在属性上使用即可!可以在set方式上使用!
使用Autowired可以不用编写set方法,前提是这个自动装配的属性在ioc容器中存在,且符合名字byName

@Nullable 字段标记了这个注解,说名这个字段可以为null
public @interface Autowired{
	boolean required() default true;
}

测试代码:

public class People {
    private String name;
    //如果显示定义了 Autowired的 required属性为fa1se,说明这个对象可以为nu11,否则不允许为空
    @Autowired(required = false)
    private Dog dog;
    @Autowired
    private Cat cat;
    }

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value="xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!

public class People {
    private String name;
    @Autowired
    @Qualifier(value = "dog222")
    private Dog dog;
    @Autowired
    private Cat cat;
}

@Resource

public class People {
    private String name;
    @Resource(name = "dog2")
    private Dog dog;
    @Resource
    private Cat cat;

小结:
@Autowired 和 @Resource 的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired 通过byType的方式实现,而且必须要求这个对象存在
  • @Resource 默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!
  • @Nullable:字段标记了这个注解,说明这个字段可以为null;
  • @Component:组件,放在类上,说明这个类被spring管理了,就是bean!
  • 执行顺序不同: @Autowired 通过byType的方式实现,@Resource 默认通过byName的方式实现

使用注解开发

  1. bean
  2. 属性如何注入
@Component // 等价于 <bean id="user" class="com.zeng.pojo.User" />
public class User {
    @Value("大大飞") // 相当于<property name="name" value"大大飞" />
    public String name;
}
  1. 衍生的注解
    @Component:有几个衍生的注解,在web开发中,会按照mvc三层架构分层!
  • dao:【@Repository】
  • service:【@Service】
  • controller:【@Controller】
    这四个注解功能都是一样的,都是代表将某个类注册到spring中,装备bean
  1. 自动装配
  2. 作用域
  3. 小结
    xml与注解:
    xml适用于任何场合!维护简单方便!
    注解只能维护自己的类,维护相对复杂!
    xml与注解最佳组合:
    xml用来管理bean!
    注解只负责完成属性的注入!
    在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持!

使用java的方式配置spring

JavaConfig是Spring的一个子项目,在spring4之后,成为了一个核心功能!
实体类:

@Component // 说明这个类被spring接管了,注册到了容器中
public class User {
    private String name;

    public String getName() {
        return name;
    }

    @Value("小小飞") // 属性注入值
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

配置类:

@Configuration // spring容器托管,注册到容器中,代表这是一个配置类,和之前的beans.xml
@ComponentScan("com.zeng.pojo")
public class Config {

    // 注册一个bean,就相当于我们之前写的一个bean标签
    // 这个方法名字,就相当于bean标签中的id属性
    // 这个方法的返回值,就相当于bean标签中的class属性
    @Bean
    public User getUser(){
        return new User(); // 返回要注入到bean的对象!
    }
}

测试:

public class MyTest {
    @Test
    public void test(){
        // 如果完全使用了配置类方式去做,就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载!
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        User user = (User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}

代理模式

SpringAop的底层就是代理模式
代理模式分类:

  • 静态代理
  • 动态代理

静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽奖类来解决
  • 真是角色:被代理的角色
  • 代理角色:代理真是角色,代理真是角色后,一般会有一些附属操作
  • 客户:访问代理对象的人
    代码步骤:
  1. 接口
  2. 真是角色
  3. 代理角色
  4. 客户端访问
    代理模式的好处:
  • 可以使真是角色的操作功能更单一,不用去关注一些公共的业务!
  • 公共业务就交给了代理角色,实现了业务的分工
  • 公共的业务发生扩展的时候,方便集中管理
    缺点:
  • 一个真实角色就会产生一个代理角色,代码量会增加

动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是直接写好的!
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口:Jdk动态代理
    • 基于类:cglib
    • java字节码实现:javaasist
      动态代理的好处:
  • 可以使真是角色的操作功能更单一,不用去关注一些公共的业务!
  • 公共业务就交给了代理角色,实现了业务的分工
  • 公共的业务发生扩展的时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理可以代理多个类,只要是实现了同一个接口即可

AOP

使用aop需要先导入一个依赖包

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.1</version>
        </dependency>
    </dependencies>

三种方式

    <!--注册bean-->
    <bean id="userService" class="com.zeng.service.UserServiceImpl"/>
    <bean id="log" class="com.zeng.log.Log"/>
    <bean id="afterLog" class="com.zeng.log.AfterLog"/>

    <!-- 方式一:使用原生Spring Api接口-->
    <!--配置aop,需要导入aop的约束-->
    <!--    <aop:config>-->
    <!--切入点:expression:表达式,execution(要执行的位置 * * * * *)-->
    <!--        <aop:pointcut id="pointcut" expression="execution(* com.zeng.service.UserServiceImpl.*(..))"/>-->
    <!--执行环绕增加-->
    <!--        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>-->
    <!--        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>-->
    <!--    </aop:config>-->

    <!--方式二:自定义类-->
    <!--    <bean id="div" class="com.zeng.div.Diy"/>-->
    <!--    <aop:config>-->
    <!--自定义切面,ref 要引用的类-->
    <!--        <aop:aspect ref="div">-->
    <!--切入点-->
    <!--            <aop:pointcut id="point" expression="execution(* com.zeng.service.UserServiceImpl.*(..))"/>-->
    <!--通知-->
    <!--            <aop:before method="befor" pointcut-ref="point"/>/-->
    <!--            <aop:after method="after" pointcut-ref="point"/>-->
    <!--        </aop:aspect>-->
    <!--    </aop:config>-->

    <!--    方法三:使用注解-->
    <bean id="annotationPointCut" class="com.zeng.div.AnnotationPointCut"/>
    <!--    开启注解支持-->
    <aop:aspectj-autoproxy/>

整合Mybatis

步骤:

  1. 导入jar包
    • junit
    • mybaits
    • mysql数据库
    • spring相关的
    • aop支持
    • mybatis-spring
  2. 编写配置文件
  3. 测试

声明式事务

事务的ACID原则:

  • 原子性
  • 一致性
  • 隔离性:多个业务可能操作同一个资源,防止数据损坏
  • 持久性:事务一旦提交,结果不会再被影响

spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要在代码中,进行事务管理
    为什么需要事务?
  • 如果不配置事务,可能存在数据提交不一致的情况
  • 如果不在spring中去配置声明式事务,就需要在代码中手动配置事务!
  • 事务在项目的开发中十分重要,涉及到数据的一致性呵完整性问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值