框架笔记 -Spring

4 篇文章 0 订阅
1 篇文章 0 订阅

Spring

核心概念

IoC(控制反转)

  • 使用对象时,由主动new对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
  • Spring提供了一个容器,称为Ioc容器,用来充当IoC思想中的外部
  • IoC容器负责对象的创建,初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
  • Spring创建对象时,会把这些对象存放在一个集合中,这个集合就是SpringIoc容器
入门案例核心代码
配置文件
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl"/>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl"/>
Dao部分代码
public interface BookDao {
    void save();
}

public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println("bookDao save");
    }
}
Service部分代码
public interface BookService {
    void save();
}


public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();
    

    @Override
    public void save() {
        System.out.println("bookService save");
        bookDao.save();
    }

}
测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");


BookDao bookDao = (BookDao) ctx.getBean("bookDao");

bookDao.save();

BookService bookService = (BookService) ctx.getBean("bookService");

bookService.save();

DI(依赖注入)

  • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
入门案例核心代码
配置文件
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl"/>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl">
    <!--  配置service与dao的关系  -->
    <!--property表示配置哪一个具体的属性-->
    <property name="bookDao" ref="bookDao"/>
</bean>
Dao部分代码
public interface BookDao {
    void save();
}

public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println("bookDao save");
    }
}
Service部分代码
public interface BookService {
    void save();
}

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    @Override
    public void save() {
        System.out.println("bookService save");
        bookDao.save();
    }
    
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

}
测试
// 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");


BookDao bookDao = (BookDao) ctx.getBean("bookDao");

bookDao.save();

BookService bookService = (BookService) ctx.getBean("bookService");

bookService.save();

  • Service中使用new形式创建的Dao对象不保留
  • Service中需要的Dao对象根据提供方法的方式进入到Servlet中
  • Service与Dao之间的关系是根据配置关联的
  • Bean默认是单例的,因为防止创建过多对象
  • 让测试用例有Spring支持:
@SpringBootTest
@RunWith(SpringRuner.class)
  • Spring中的对象是单例

@Autowired和@Resource注解区别

@Resource按照名称注入,@Autowired按照类型注入,@Qualifire指定要注入的bean名称

适合交给容器进行管理的Bean

  • 客观层对象

  • 业务层对象

  • 数据层对象

  • 工具对象

不适合交给容器进行管理的Bean

  • 封装实体的域对象

Bean实例化

bean本质上就是对象,创建bean使用构造方法完成
能new的对象就能配置bean,spring创建对象是使用类的无参构造创建的

方式1: 构造方法实例化bean

代码同上方

方式2: 使用静态工厂实例化bean

  • 配置文件
<!--  使用静态工厂示例化bean  -->
<bean id="orderDao" class="work.xlrong.factory.OrderDaoFactory" factory-method="getOrderDao"/>
  • dao部分代码
public interface OrderDao {
    void save();
}

public class OrderDaoImpl implements OrderDao {
    @Override
    public void save() {
        System.out.println("orderDao save");
    }
}
  • factory部分代码
public class OrderDaoFactory {
    public static OrderDao getOrderDao() {
        return new OrderDaoImpl();
    }
}
  • 测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");

orderDao.save();

方式3: 使用实例工厂实例化bean

  • 配置文件
<!--  使用实例工厂实例化bean  -->
<bean id="userFactory" class="work.xlrong.factory.UserDaoFactory"/>

<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>
  • Dao部分代码
public interface UserDao {
    void save();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("userDao save");
    }
}
  • Factory部分代码
public class UserDaoFactory {
    public UserDao getUserDao() {
        return new UserDaoImpl();
    }
}
  • 测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

UserDao userDao = (UserDao) ctx.getBean("userDao");

userDao.save();

方式4: 使用FactoryBean实例化Bean

  • 配置文件
<!--  使用FactoryBean实例化Bean  -->
<bean id="userDao" class="work.xlrong.factory.UserDaoFactoryBean"/>
  • Dao部分代码
public interface UserDao {
    void save();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("userDao save");
    }
}
  • FactoryBean部分代码
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    /**

   * 代替原始实例工厂中创建对象的方法

        * @return
           @throws Exception
               */
              @Override
              public UserDao getObject() throws Exception {
          return new UserDaoImpl();
              }


    /**
     * 获取对象的类型
     *
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
    
    /**
     * 该对象是否是单例的
     * 
     * @return
     */
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }

}

依赖注入方式

方式1: seter

  • 配置文件
<bean id="userDao" class="work.xlrong.dao.impl.UserDaoImpl"/>
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl"/>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl">
	<property name="bookDao" ref="bookDao"/>
	<property name="userDao" ref="userDao"/>
</bean>
  • Dao部分代码
public interface UserDao {
    void save();
}


public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("userDao save");
    }
}

public interface BookDao {
    void save();
}

public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println("bookDao save");
    }
}
  • Service部分代码
public interface BookService {
    void save();
}


public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

    @Override
    public void save() {
        System.out.println("bookService save");
        bookDao.save();
        userDao.save();
    }
    
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

}
  • 测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookService bookService = (BookService) ctx.getBean("bookService");

bookService.save();
  • 存在成员变量时,代码改动为
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl">
	<property name="connectionNum" value="10"/>
	<property name="databaseName" value="mysql"/>
</bean>
public class BookDaoImpl implements BookDao {
    private int connectionNum;
    private String databaseName;


    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }
    
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
    
    @Override
    public void save() {
        System.out.println("bookDao save..." + connectionNum + "..." + databaseName);
    }

}

构造器注入

  • 配置文件
<bean id="userDao" class="work.xlrong.dao.impl.UserDaoImpl"/>
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl">
	<constructor-arg name="connectionNum" value="10"/>
	<constructor-arg name="databaseName" value="mysql"/>
</bean>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl">
	<constructor-arg name="bookDao1" ref="bookDao"/>
	<constructor-arg name="userDao1" ref="userDao"/>
</bean>
<bean id="userDao" class="work.xlrong.dao.impl.UserDaoImpl"/>
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl">
	<constructor-arg type="int" value="10"/>
	<constructor-arg type="java.lang.String" value="mysql"/>
</bean>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl">
	<constructor-arg name="bookDao1" ref="bookDao"/>
	<constructor-arg name="userDao1" ref="userDao"/>
</bean>
<bean id="userDao" class="work.xlrong.dao.impl.UserDaoImpl"/>
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl">
	<constructor-arg index="0" value="10"/>
	<constructor-arg index="1" value="mysql"/>
</bean>

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl">
	<constructor-arg name="bookDao1" ref="bookDao"/>
	<constructor-arg name="userDao1" ref="userDao"/>
</bean>
  • Dao部分代码
public interface UserDao {
    void save();
}


public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("userDao save");
    }
}

public interface BookDao {
    void save();
}

public class BookDaoImpl implements BookDao {
    private int connectionNum;
    private String databaseName;

    public BookDaoImpl(int connectionNum, String databaseName) {
        this.connectionNum = connectionNum;
        this.databaseName = databaseName;
    }
    
    @Override
    public void save() {
        System.out.println("bookDao save..." + connectionNum + "..." + databaseName);
    }

}
  • Service部分代码
public interface BookService {
    void save();
}

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao1, UserDao userDao1) {
        this.bookDao = bookDao1;
        this.userDao = userDao1;
    }
    
    @Override
    public void save() {
        System.out.println("bookService save");
        bookDao.save();
        userDao.save();
    }

}
  • 测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookService bookService = (BookService) ctx.getBean("bookService");

bookService.save();

总结

更推荐setter的方法

自动装配

按类型装配的话,名称需唯一

<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl" autowire="byType"/>
<bean id="bookService" class="work.xlrong.service.impl.BookServiceImpl" autowire="byName"/>
...

集合装配

  • 配置文件
<bean id="bookDao" class="work.xlrong.dao.impl.BookDaoImpl">
    <property name="array">
        <array>
            <value>100</value>
            <value>200</value>
            <value>300</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>xlrong</value>
            <value>hello</value>
            <value>spring</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>xlrong</value>
            <value>hello</value>
            <value>hello</value>
            <value>spring</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="country" value="中国"/>
            <entry key="province" value="河南"/>
            <entry key="city" value="郑州"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="country">中国</prop>
            <prop key="province">河南</prop>
            <prop key="city">郑州</prop>
        </props>
    </property>
</bean>
  • Dao部分代码
public interface BookDao {
    void save();
}

public class BookDaoImpl implements BookDao {
    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    private Properties properties;

    public void setArray(int[] array) {
        this.array = array;
    }
    
    public void setList(List<String> list) {
        this.list = list;
    }
    
    public void setSet(Set<String> set) {
        this.set = set;
    }
    
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    
    @Override
    public void save() {
        System.out.println("bookDao save...");
    
        System.out.println("遍历集合: " + Arrays.toString(array));
        System.out.println("遍历List" + list);
        System.out.println("遍历Set" + set);
        System.out.println("遍历Map" + map);
        System.out.println("遍历Properties" + properties);
    }

}
  • 测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookDao bookDao = ctx.getBean(BookDao.class);

bookDao.save();

加载properties

步骤

  1. context -> 选property-placeholder
  2. 配置xml配置文件
  3. 配置property文件
  4. 引入配置文件中数据: ${}

需要加载多个配置文件

  • 多个文件之间加逗号
  • <import resource="classpath:资源路径">
  • *.property

容器

创建容器方式

  • 方式1:
ClassPathXmlApplicationContext
  • 方式2:
FileSystemXmlApplicationContext

获取方式

  • 方式1: 使用bean名称获取
BookDao bookDao = (Bookdao) ctx.getBean("bookDao");
  • 方式2: 使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
  • 方式3: 使用bean类型获取(只能有一个相同类型)
BookDao bookDao = ctx.getBean(BookDao.class);

多配置文件时

  • 方式1: 直接加载多个配置文件
new ClassPathXmlApplicationContext(".xml", ".xml");
  • 方式2: 在核心配置文件中import多个配置文件,只加载核心配置文件

注解开发定义bean

常用注解/配置

  • @Component: 声明一个组件,value是它的name
  • @Repository: 数据仓库
  • <context:component-scan base-package="">
  • @Service
  • @AutoWired
  • @Controler

纯注解开发

注解
  • @Configuration: 表明这是一个配置类
  • @ComponentScan(""): 扫描的包,如果有多个,用数组的方式添加
  • @Scopr: 作用范围单例还是多例

自动装配

注解
  • @AutoWired
  • @Qualifier(""): 指定bean的名称、依赖于AutoWired
  • @Value(""): 简单类型的自动注入
  • @PropertySource(""): 指定数据源,写在配置类中,多文件使用大括号数组,不支持通配符

第三方bean管理

  • 使用@Bean配置第三方bean
  • 使用@ComponentScan扫描
  • 使用@Import

Spring整合Mybatis+Junit

整合Junit常用注解

  • @RunWith(SpringJunit4ClassRunner.class):
  • @ContextConfiguration(classes = SpringConfig.claaa): 核心配置文件

动态代理

在不修改代码的前提下对程序的功能进行增强,行为本身叫做面向切面编程或者AOP

大体步骤

  1. 获取原始对象(被代理的对象)
  2. 动态代理:
    1. 参数1: 被代理对象的类加载器
    2. 参数2: 被代理对象实现的接口们
    3. 参数3: 代理的行为
  3. 执行方法

AOP

面向切面编程,指导开发者如何组织程序结构

作用

在不惊动原始设计的基础上进行功能增强

核心概念

  • 连接点: 程序执行过程中的任意位置,粒度为执行方法,抛出异常、设置变量等,在SpringAOP中,理解为方法的执行
  • 切入点: 匹配连接点的式子,在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
    • 一个具体方法: 某接口中的五形参无返回值的一个方法
    • 匹配多个方法: 例: 所有的save方法,所有get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法
  • 通知: 在切入点处执行的操作,也就是共性功能,在SpringAOP中,功能最终以方法的形式呈现
  • 通知类: 定义通知的类
  • 切面: 描述通知与切入点的对应关系

注解

  • @PointCut("execution(void ...method())"): 切入点
  • @Before("..()")
  • @Aspext: 该类是AOP
  • 核心配置文件中: @EnableAspectJAutoProxy

AOP工作流程

  1. Spring容器启动
  2. 读取所有切面中的切入点
  3. 初始化bean,判定bean对应的类中的方法是否匹配到任意切入点
    1. 匹配失败: 创建失败
    2. 匹配成功: 创建原始对象(目标对象)的代理对象
  4. 获取bean执行方法
    1. 获取bean,调用方法并执行,完成操作
    2. 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容

AOP切入点表达式

  • 切入点: 要进行增强的方法
  • 切入点表达式: 要进行增强的方法的描述方式

语法格式

  • 执行某包下的某接口中的无参数某方法
execution(void work.xlrong.dao.BookDao.update())
  • 执行某包下某实现类中的某无参数方法
execution(void work.xlrong.dao.impl.BookDaoImpl.update())
常用通配符
  • *: 单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

  • ..: 多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

  • +: 常用于匹配子类类型

  • 在切入点中,可以使用与或非符号

    • && / and: 与
    • || / or: 或
    • !: 非

AOP通知类型

AOP通知描述了抽取的共性问题,根据共性功能抽取的位置不同

AOP的5种通知

  • 前置通知: @Before
  • 后置通知: @After
  • 环绕通知: 注意返回值
@Around("pt()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("before");


    // 表示对原始操作的调用
    pjp.proceed();
    
    System.out.println("after");

}
  • 返回后通知:
  • 抛出异常后通知:

Spring事物

在数据层保障一系列的数据库操作同成功同失败
在数据层或业务层保障一系列的数据库操作同成功同失败

注解

  • @Transactional: 开启事务

工具类

  • 可以用于MD5加密:
  String md5DigestAsHex = DigestUtils.md5DigestAsHex((password + salt).getBytes());
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值