Spring

Spring

IOC的Bean的管理

IOC的底层原理

  1. 使用工厂模式和反射,通过构造方法和set方法来注入属性;
  2. DI依赖注入使得对象之间的关系得到了解耦,降低了程序的耦合性;

1.xml注入

<util:list id="list">
        <value>撒哈拉沙漠</value>
        <value>月亮与九便士</value>
        <value>小王子</value>
</util:list>
    <bean id="person" class="com.Person">
        <property name="user" ref="user"/>
        <property name="name" value=""/>
        <property name="list" ref="list"/>
    </bean>
    <bean id="user" class="com.User"/>
    <bean id="myBean" class="com.myBean"/>

2.Spring有两种类型的Bean,一种普通Bean和一种工厂bean(FactoryBean)

  1. 普通Bean在配置文件中定义的返回类型就是Bean类型;

  2. 工厂Bean在配置文件中定义的返回类型和Bean类型可以不一样;

    1. 创建类,实现FactoryBean接口;

    2. 实现接口中的方法,定义返回的Bean的类型;

      import org.springframework.beans.factory.FactoryBean;
      public class myBean implements FactoryBean<User> {
          public User getObject() throws Exception {
      
              return new User();
          }
      
          public Class<?> getObjectType() {
              return User.class;
          }
      
          public boolean isSingleton() {
              return true;
          }
      }
      

3.Bean的作用域

  1. 在spring中Bean默认是单例对象;
  2. 在Bean的配置中scope有两个选择:singleton和prototype;
    1. 设置是singleton时,在spring加载配置文件的时候就会创建单例对象;
    2. 设置是prototype时,在getBean时创建一个多实例对象;

4.Bean的生命周期

  1. 通过构造方法来创建Bean实例;(一般为无参构造)
  2. 给Bean的属性设置值和注入对其它Bean的引用;(通过set方法)
  3. 把Bean的实例传递给Bean的后置处理器;BeanPostProcessor接口的实现
  4. 调用Bean的初始化方法;(需要自己配置初始化方法)
  5. 把Bean的实例传递给Bean的后置处理器;BeanPostProcessor接口的实现
  6. Bean可以被使用了;
  7. 当容器被关闭时,调用Bean的销毁方法;(需要自己配置销毁方法)

5.XML引入外部对象

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="name" value="${name}"/>
        <property name="password" value="${password}"/>
        <property name="driver" value="${driverClass}"/>
        <property name="url" value="${url}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/> <--导入配置文件-->

使用注解管理Bean

简化xml配置

1.Spring针对Bean管理中创建对象的注解

  1. @Component

  2. @Repository

  3. @Service

  4. @Controller

    针对不同层,使用不同的注解,但它们的作用都是一样的;

2.基于注解实现属性的注入

  1. @Autowired;根据类型
  2. @Qualifier;根据名称
  3. @Resource;可以根据类型或名称
  4. @Value;注入普通类型

3.完全注解开发

@Configuration//申明这是个配置类
@ComponentScan(basePackages = {"annotation"})//指定Bean的扫描的包
public class Configuration1 {
}

AOP

1.概念:原理就是动态代理

  1. 利用AOP可以对业务逻辑的各个部分进行隔离,从而使的业务逻辑的各部分的耦合度降低,提高程序的可重用性,同时提高开发效率;
  2. 在不修改原有业务代码的基础上,添加新的功能,比喻日志,事务;

2.AOP的底层原理

  1. 动态代理;

    1. 有借口:JDK的动态代理;
    2. 无接口:CGLIB动态;

3.术语

  1. 连接点

    1. 类中可以被增强的方法;
  2. 切入点

    1. 实际被增强的方法;
  3. 通知(增强)

    1. 实际被增强的逻辑部分被称为通知;
    2. 通知的类型;
      • 前置通知
      • 后置通知
      • 环绕通知
      • 异常通知
      • 最终通知
  4. 切面

    1. 是一个动作:把通知应用到切入点的过程;

4.spring的aop操作

  1. aop简介;

    1. spring是基于aspectj来实现aop操作的;
    2. aspectj不是spring的组成部分,是一个独立的aop框架,一般吧aspectj和spring框架一起使用;
  2. 使用配置xml或注解;

    1. import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.*;
      import org.springframework.stereotype.Component;
      @Component
      @Aspect
      public class UserProxy {
          //相同切入点的抽取
          @Pointcut(value = "execution(* aopannotation.User.*(..))")//aop表达式
          public void point(){
          }
          @Before(value = "point()")//用这个来代替相同的aop表达式
          public void before(){
              System.out.println("Before前置通知");
          }
          @After(value = "point()")
          public void after(){
              System.out.println("After最终通知");
          }
          @AfterReturning(value = "execution(* aopannotation.User.*(..))")
          public void return1(){
              System.out.println("AfterReturning后置通知");
          }
          @AfterThrowing(value = "execution(* aopannotation.User.*(..))")
          public void exception(){
              System.out.println("AfterThrowing异常通知");
          }
          @Around(value = "execution(* aopannotation.User.*(..))")
          public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
              System.out.println("Around环绕通知前");
              proceedingJoinPoint.proceed();
              System.out.println("Around环绕通知后");
              return proceedingJoinPoint;
          }
      }
      Around环绕通知前
      Before前置通知
      my name is 123
      AfterReturning后置通知
      After最终通知
      Around环绕通知后
      
  3. 使用@Order()设置优先级,来使得对相同方法的不同增强类进行增强;

    1. @Component
      @Aspect
      @Order(1)//数字越小,优先级越高
      Around环绕通知前Order(1)
      Before前置通知Order(1)
      Around环绕通知前Order(3)
      Before前置通知Order(3)
      my name is 123
      AfterReturning后置通知Order(3)
      After最终通知Order(3)
      Around环绕通知后Order(3)
      AfterReturning后置通知Order(1)
      After最终通知Order(1)
      Around环绕通知后Order(1)
      
  4. 完全使用注解

    @Configuration
    @ComponentScan(basePackages = {"aopannotation"})
    @EnableAspectJAutoProxy(proxyTargetClass = true)//开启aop
    //相当于下面的内容
    <context:component-scan base-package="aopannotation"/>
    <aop:aspectj-autoproxy/>//开启aop
    

JDBCTemplate

  1. 使用jdbctemplate操作数据库

    @Repository
    public class UserDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
        public void add(User user){
            String sql="insert into user values(?,?,?)";
            int update = jdbcTemplate.update(sql, user.getId(), user.getName(), user.getPwd());
            System.out.println(update);
        }
    
        public void update(@NotNull User user) {
    
            String sql="update user set user.name=?,user.pwd=? where id=?;";
            int update = jdbcTemplate.update(sql, user.getName(), user.getPwd(), user.getId());
            System.out.println(update);
        }
    
        public void delete(int id) {
            String sql="delete from user where id=?;";
            int update = jdbcTemplate.update(sql, id);
            System.out.println(update);
        }
        public int count(){
            String sql="select count(*) from user";
            return jdbcTemplate.queryForObject(sql, Integer.class);
        }
        public User queryById(int id){
            String sql="select * from user where id=?";
            return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
        }
        public List<User> findAll(){
            String sql="select * from user where id between 12 and 88";
            return jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
        }
        public void batchAddUser(List<Object[]> list){
            String sql="insert into user values(?,?,?)";
            int[] ints = jdbcTemplate.batchUpdate(sql, list);
            System.out.println(Arrays.toString(ints));
        }
        public void batchUpdateUser(List<Object[]> list){
            String sql="update user set name=?,pwd=? where id=?;";
            int[] ints = jdbcTemplate.batchUpdate(sql, list);
            System.out.println(Arrays.toString(ints));
        }
        public void batchDeleteUser(List<Object[]> list){
            String sql="delete from user where id=?;";
            int[] ints = jdbcTemplate.batchUpdate(sql, list);
            System.out.println(Arrays.toString(ints));
        }
    }
    //需要配置jdbcTemplate
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
    </bean>
    

Transaction

  1. 使用事务:注解或xml;

  2. 一般把事务添加到三层结构中的service层中;

    1. 两种方式:编程式和声明式;
    2. 声明式事务管理,底层使用的AOP原理;
    <bean id="transactionManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManage"/>
    
  3. 事务的传播机制;

    1. required:
    2. required_new:
    3. supports:
    4. not_supports:
    5. mandatory:
    6. never:
    7. nested:
  4. 隔离界别:1.默认数据库的级别

    ​ 2.数据库的四种默认级别

  5. 超时时间:timeout

  6. readonly:是否只读,默认为false;

  7. rollbackfor:设置哪些异常进行回滚;

  8. norollbackfor:设置哪些异常不进行回滚;

Spring5的新功能

1、整合日志框架

  1. 整合Log4j2日志;

  2. log4j-api;log4j-core;log4j-slf4j-impl;slf4j-api;

  3. 固定的配置xml文件;

  4. <?xm1 version=1.0" encoding="UTE-8"?>
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!--Configuration后面的status用于设置1og4j2自身内部的信息输出,可以不设置,当设置成trace时,可以看到log4j2内部
    各种详细输出-->
    <configuration status="OFF">
        <!--先定义所有的appender-->
        <appenders>
            <!--输出日志信息到控制台-->
            <console name="Console" target="SYSTEM_OUT">
                <!--控制日志输出的格式-->
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            </console>
        </appenders>
        <!--然后定义logger,只有定义了logger并引入的appender, appender才 会生效- ->
        <!-root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认的日志输出-->
        <loggers>
            <root level="info">
                <appender-ref ref="Console"/>
            </root>
        </loggers>
    </configuration>
    
  5. Logger logger = LoggerFactory.getLogger(T2.class);
    //使用logger来手动输出日志信息
    

2、@Nullable注解

  1. @Nullable注解可使用在方法,属性,方法参数上,表示方法返回可为空,属性可为空,参数可为空;

3、函数式注册对象

  1. public void teat2() {
        //使用函数式风格来注册Bean
        GenericApplicationContext context = new GenericApplicationContext();
        context.refresh();
        context.registerBean("user1",User.class, 1,"123","18");
        User user1 = (User) context.getBean("user1");
        User user2 = (User) context.getBean("user1");
        System.out.println(user1==user2);
        System.out.println(user1);
    }
    true
    User{id=1, name='123', pwd='18'}
    

4、整合JUnit5单元测试

  1. //使用的是Junit4
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = txConfig.class)
    //使用的是Junit5
    @ExtendWith(SpringExtension.class)
    @ContextConfiguration(classes = {txConfig.class})
    //把上面的两个注解合并为下面一个
    @SpringJUnitConfig(value = {txConfig.class})
    

5、Spring webflux使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值