Spring的解耦
通过工厂类读取配置文件创建对象,以此降低耦合度,使用容器来确保创建出的对象是单例的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--IOC环境搭建-->
<bean id="userDao" class="Dao.DaoImpl.UserDaoImpl"></bean>
<bean id="userService" class="service.UserService"></bean>
</beans>
//IOC简单使用
public class main {
public static void main(String[] args) {
ApplicationContext alc=new ClassPathXmlApplicationContext("bean.xml");
UserDao userDao = (UserDao) alc.getBean("userDao");
UserService userService = alc.getBean("userService", UserService.class);
userDao.print();
System.out.println(userService);
}
}
ApplicationContext的三个常用实现类:
ClassPathXmLApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。FileSystemXmLApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
AnnotationConfigAppLicationContext:它是用于读取注解创建容器的。
核心容器的两个接口引发出的问题;
ApplicationContext:单例对象适用 常采用此接口
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
BeanFactory:多例对象使用
它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
<!--创建Bean对象的三种方式-->
<!--使用默认构造函数构造-->
<bean id="userDao" class="Dao.DaoImpl.UserDaoImpl"></bean>
<!--使用工厂方法构造-->
<bean id="factory" class="factory.UserFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="createUser"></bean>
<!--使用工厂静态方法构造-->
<bean id="userDao" class="factory.UserFactory" factory-method="createUser"></bean>
bean标签的scope属性:
作用:用干指定bean的作用范围
取值:常用的就是单例的和多例的
- singleton:单例的(默认值)
- prototype:多例的
- request:作用于web应用的请求范围
- session:作用于web应用的会话范围
- global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
bean的生命周期
单例:伴随容器的产生和销毁
多例:使用的时候才产生,长时间不使用会被java回收器回收
依赖注入:
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护。
能注入的数据:
- 基本类型和string
- 其他bean类型(在配置文件中或者注解配置过的bean)
- 复杂类型/集合类型
注入的方式:有三种
- 第一种:使用构造函数提供
- 第二种:使用set方法提供
- 第三种:使用注解提供
构造函数注入
在bean标签内部使用标签constructor-arg
标签中的属性
- type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
- index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
- name:用于指定给构造函数中指定名称的参数赋值 常用的
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
set方法注入
在bean标签内部使用标签property
- name:用于指定给构造函数中指定名称的参数赋值
- value:用于提供基本类型和String类型的数据
- ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
复杂/集合类型
用于给List结构集合注入的标签:
list array set
用于个Map结构集合注入的标签:
map props
结构相同,标签可以互换
使用spring的注解需要在xml配置文件中,在标签context:component-scan中告知spring扫描的包
Spring常用注解
@Component用于把当前类存入spring容器中,其中的属性value用于指定bean的id
@Autowired:
作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
@Qualifier:
作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。可以用于注入参数
属性:value:用于指定注入bean的id。
@Value:
作用:用于注入基本类型和String类型的数据
属性:value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
@Scope:
作用:用于指定bean的作用范围属性:
value:指定范围的取值。常用取值:singleton prototype
@PreDestroy:
作用:用于指定销毁方法
@PostConstruct:
作用:用于指定初始化方法
@Configuration:
作用:指定当前类是一个配置类
@ComponentScan:
作用:用于通过注解指定spring在创建容器时要扫描的包
属性value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
@PropertySource(“classpath:JDBC.properties”):
加载配置文件,classpath表示类路径下
@Bean:
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中属性:
name:用于指定bean的id。当不写时,默认值是当前方法的名称
当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象香找的方式和Autowired往解的作用是一样的
@Import:
作用:用于导入其他的配置类
属性:value:用于指定其他配置类的字节码。
Spring整合junit的配置
1、导入spring整合junit的jar(坐标)
2、使用Junit提供的一个注解把原有的main方法昔换了.替换成spring提供的
@Runwith(SpringJunit4ClassRunner.class)
3、告知spring的运行器. spring和ioc创建是基于xmL还是注解的、并且说明位置
@ContextConfiguration()
locations:指定xml文件的位置,加上classpath关键字。表示在类路径下classes:指定注解类所在地位置
spring中基于XML的AOP配置步骤
1、把通知Bean也交给spring来管理
2、使用aop:config标签表明开始AOP的配置
3、使用aop:aspect标签表明配置切面
id属性:是给切面提供一个唯一标识ref属性:是指定通知类bean的Id。
4、在aop:aspect标签的内部使用对应标签来配置通知的类型
aop: before:表示配置前置通知
method属性:用于指定Logger类中哪个方法是前置通知
pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强
切入点表达式的写法:
关键字:execution(表达式)
表达式:访问修饰符 返回值包名.包名.包名…类名.方法名(参数列表)
注解配置AOP
1.在类前加上注解@Aspect,表示这个类为切面类
2.配置切入点表达式
@Pointcut("execution(public * XML.Dao.DaoImpl.*.*(..)) ")
private void pt1(){};
3.使用@Before等配置通知
Spring中基于XML配置事务管理器
1、配置事务管理器
<bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
2、配置事务的通知
此时我们需要导入事务的约束 tx名称空间和约束.同时也需要aop的使用tx:advice标签配置事务通知
属性:
id:给事务通知起一个唯一标识
transaction-manager:给事务通知提供一个事务管理器引用
<tx:advice id="txAdvice" transaction-manager="transaction">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
3、配置AOP中的通用切入点表达式
<aop:config>
<aop:pointcut id="txManage" expression="execution(public * XML.Dao.DaoImpl.*.*(..)))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txManage"></aop:advisor>
</aop:config>
注解配置事务控制
1、配置事务管理器
<bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
2、开启spring对事务注解的支持
<tx:annotation-driven transaction-manager="transaction"></tx:annotation-driven>
纯注解配置事务管理
在配置类前加上@EnableTransactionManagement开启事务注解支持,在需要事务控制的类前加上@Transactional,开启对该类的事务控制