1 Spring配置文件
1.1 详解
Bean标签基本配置 用于配置对象交由Spring创建。默认情况调用的是类中的无参构造函数(若没有无参构造函数则不能创建成功)
id:容器中的唯一标识
class:Bean的全限定名
范围配置
scope:指对象的作用范围,取值如下
取值为singleton时,userDao地址相同,表示为一个唯一的userDao Bean的创建时机为加载xml文件时
生命周期:
对象创建:当应用加载,创建容器时,对象创建
对象运行:容器在,对象一直存活
对象销毁:销毁容器时,对象销毁
取值为prototype时,userDao地址不相同,表示为两个的userDao Bean的创建时机为getBean时
生命周期:
对象创建:使用对象时,创建实例
对象运行:对象在使用中,则一直存活
对象销毁:当长时间没有强引用指向该对象,被垃圾回收器回收
生命周期配置
init-method:指定类中的初始化方法名
destroy-method:指定类中销毁方法名
Bean实例化三种方式
1、无参构造
2、工厂静态
先创建静态工厂 再修改配置,class属性改为静态工厂类,为factory-method属性添加静态方法
3、工厂实例 配置通过两个Bean完成,先配置工厂的Bean,再通过factory-bean、factory-method俩属性使用工厂的bean
1.2 依赖注入
依赖注入(Dependency Injection):Spring框架核心IOC的具体实现
在Spring容器中将UserDao设置在UserService内部 Bean依赖注入方式
1、构造方法
2、set方法
形式一:
UserService对应代码 xml文件里配置
————————————————-分割线——————————————————-
!!!!如果通过new的形式创建UserService对象,在调用save方法时会出现空指针异常 原因在于UserServiceImpl类中的UserDao没有赋值,通过new的形式,不是从IOC容器中取值,即UserDao没注入
形式二:
仅需修改配置文件 1、引入命名空间
xmlns:p="http://www.springframework.org/schema/p"
2、修改注入方式
<bean id="userService" class="wsw.Service.Impl.UserServiceImpl" p:userDao-ref="userDao"/>
Bean依赖注入的数据类型
1 普通数据类型、2 集合数据类型、3 引用数据类型
1、普通数据类型 配置文件 :property属性里 对象引用ref 普通数据用value
<bean id="userDao" class="wsw.Dao.Impl.UserDaoImpl" >
<property name="a" value="李云龙"/>
<property name="b" value="48"/>
</bean>
2、集合数据类型 配置文件: 其中user1、user2的bean 在map中使用
<bean id="userDao" class="wsw.Dao.Impl.UserDaoImpl">
<property name="strlist">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property>
<property name="maps">
<map>
<entry key="u1" value-ref="user1"/>
<entry key="u2" value-ref="user2"/>
</map>
</property>
<property name="properties">
<props>
<prop key="1">1</prop>
<prop key="2">2</prop>
<prop key="3">3</prop>
</props>
</property>
</bean>
<bean id="user1" class="wsw.Domain.User">
<property name="username" value="大大怪将军"/>
<property name="addr" value="地球"/>
</bean>
<bean id="user2" class="wsw.Domain.User">
<property name="username" value="小小怪下士"/>
<property name="addr" value="地球"/>
</bean>
1.3 分模块开发
引入其他配置文件
<import resource="applicationContext-xxx.xml"/>
2 Spring相关API
ApplicationContext实现类:
1、ClassPathXmlApplicationContext(推荐使用) 从类的根路径下加载配置文件
2、FileSystemXmlApplicationContext 从磁盘路径加载配置文件,配置文件可在磁盘的任意位置(使用绝对路径)
3、AnnotationConfigApplicationContext 使用注解配置容器对象时,需使用此类来创建spring容器,以此来读取注解。
getBean()方法使用
当存在多个同一类型的,只能使用方式一 id的形式 !!!!!!
3 Spring配置数据源
数据源,即连接池,为提高程序性能
先实例化数据源,初始化部分连接资源;使用连接资源时从数据源中获取;使用完毕后将连接资源归还给数据源。
常见数据源:DBCP、C3P0、BoneCP、Druid等
3.1 数据源开发步骤
1 导入数据源的坐标 和 数据库驱动坐标
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
2 创建数据源对象 3 设置数据源的基本连接数据
//测试手动创建Druid数据源
@Test
public void test1() throws Exception {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/ssm");
dataSource.setUsername("root");
dataSource.setPassword("123456");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
//测试手动创建c3p0数据源
@Test
public void test2() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
dataSource.setUser("root");
dataSource.setPassword("123456");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
4 使用数据源获取连接资源 和 归还连接资源
——————————————————-分割————————————————— 为解耦合,需抽取jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=123456
通过ResourceBundle的getBundle方法获取文件名,进而获取各参数,重复上述配置
//测试手动创建c3p0数据源(加载配置文件)
@Test
public void test3() throws Exception {
//读取配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("jdbc.driver");
String url = bundle.getString("jdbc.url");
String username = bundle.getString("jdbc.username");
String password = bundle.getString("jdbc.password");
//创建数据源对象,设置连接参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
3.2 spring配置数据源
DataSource由Spring容器进行创建 xml文件配置Bean
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</bean>
property的name 对应的是类的set方法名
测试方法:
//测试Spring容器创建c3p0数据源对象
@Test
public void test4() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
3.3 spring加载properties文件
命名空间添加:
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
随后配置
<!--加载外部properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
4 Spring注解开发
4.1 注解开发
原始注解:
* @Component:使用在类上 用于实例化Bean
* @Controller:使用在web层类上 用于实例化Bean
* @Service:使用在service层类上 用于实例化Bean
* @Repository:使用在dao层类上 用于实例化Bean
* @Autowired:使用在字段上 用于根据类型依赖注入
* @Qualifier:结合@Autowired一起使用 用于根据名称进行依赖注入
* @Resource:相当于@Autowired+@Qualifier,按照名称进行注入
@Resource(name="xxx")
* @Value:注入普通属性
* @Scope:标注Bean的作用范围 singleton单例 prototype多例
@PostConstruct:使用在方法上 标注该方法是Bean的初始化方法
@PreDestroy:使用在方法上 标注该方法是Bean的销毁方法
其中Controller、Service、Repository 与Component效果相同,只是在不同层上用(区分使用)
使用注解开发,需在applicationContext.xml中配置组件扫描。 作用:指定哪个包及其子包下的Bean需进行扫描,以识别使用注解配置的类、字段和方法。
<context:component-scan base-package="xxx"></context:component-scan>
新注解:
@Configuration:用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@ComponentScan:用于指定Spring在初始化容器时要扫描的包
@Bean:使用在方法上,标注将该方法的返回值以指定名称存储在Spring容器中
@PropertySource:用于加载.properties文件中的配置
@Import:用于导入其他配置类
创建两个配置类 SpringConfiguration类为核心类
@Configuration //标志该类为核心配置类
@ComponentScan("wsw")//<context:component-scan base-package="wsw"/>
@Import(DataSourceConfiguration.class) //<import resource=""/>
public class SpringConfiguration {
}
DataSourceConfiguration类为连接数据库类
@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>
public class DataSourceConfiguration {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource getDataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
5 Spring集成Junit
2 使用@Runwith注解替换原来的运行期
3 使用@ContextConfiguration指定配置文件或配置类
4 使用@Autowired注入需要测试的对象
6 Spring AOP
Aspect Oriented Programming。面向切面编程 通过预编译方式 和 运行期动态代理实现程序功能的统一维护的一种技术
作用:
程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:
减少重复代码,提高开发效率,便于维护
常用术语: · Target(目标对象):代理的目标对象 · Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类 · Joinpoint(连接点):即目标对象的方法 · Pointcut(切入点):即要进行增强的目标对象方法 · Advice(通知/增强):增强方法 · Aspect(切面):即增强方法与要被增强的目标方法结合 · Weaving(织入):指切面的过程
编写步骤
· 编写核心业务代码(目标类的目标方法)
· 编写切面类,切面类中有通知(增强方法)
· 在配置文件中,配置织入关系,即将哪些通知与连接点结合
6.1 Spring的AOP
动态代理技术
1 JDK代理:基于接口的动态代理,运行期间基于接口动态地生成代理对象 2 cglib代理:基于父类的动态代理,动态生成子对象
cglib的代理对象是目标对象的子类,而jdk代理对象和目标对象都实现了目标接口,jdk的代理对象还继承了Proxy
基于JDK的动态代理 增强函数advice
public class Advice {
public void before(){
System.out.println("前置增强.");
}
public void after(){
System.out.println("后置增强.");
}
}
目标对象方法target
public class Target implements TargetInterface {
@Override
public void save() {
System.out.println("save running............");
}
}
代理对象方法proxytest
public class ProxyTest {
public static void main(String[] args) {
//创建目标对象
final Target target = new Target();
//获得增强对象
final Advice advice = new Advice();
//返回值为动态生成的代理对象
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),//目标对象类加载器
target.getClass().getInterfaces(),//目标对象 相同的接口字节码对象数组
new InvocationHandler() {
//调用代理对象的任何方法,其实质是执行的均是invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置增强
advice.before();
Object invoke = method.invoke(target, args);//执行目标方法
//后置增强
advice.after();
return invoke;
}
}
);
proxy.save();
}
}
proxytest
public class ProxyTest {
public static void main(String[] args) {
//创建目标对象
final Target target = new Target();
//获得增强对象
final Advice advice = new Advice();
//返回值为动态生成的代理对象 基于cglib
//1 创建增强器
Enhancer enhancer = new Enhancer();
//2 设置父类(目标)
enhancer.setSuperclass(Target.class);
//3 设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//前置
advice.before();
Object invoke = method.invoke(target, args);//执行目标方法
//后置
advice.after();
return invoke;
}
});
//4 创建代理对象
Target proxy = (Target) enhancer.create();
proxy.save();
}
}
6.2 基于XML的AOP开发
步骤: 1 导入AOP相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
5 在applicationContext.xml中配置织入关系 头部信息
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
切点表达式 语法:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
·访问修饰符可省略 ·返回值类型、包名、类名、方法名可使用星号*代表任意 ·包名与类名之间一个点.代表当前包下的类,两个点…表示当前包及其子包下的类 ·参数列表可使用两个点…表任意个数、任意类型的参数列表
通知 语法:
<aop:通知类型 method= "切面类中方法名" pointcut= "切点表达式 " />
切点表达式抽取 使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式
6.3 基于注解的AOP开发
步骤: 1 创建目标接口、目标类 2 创建切面类 3 将目标类和切面类的对象创建权交给spring
5 在配置文件中开启组件扫描和AOP的自动代理 需要引入头部信息
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
配置文件中代码
<!--开启组件扫描-->
<context:component-scan base-package="wsw.AOP" />
<!--AOP自动代理-->
<aop:aspectj-autoproxy/>
6 测试
7 Spring 事物控制
7.1 编程式事务控制相关对象
2 TransactionDefinition 2.1 事务隔离级别 设置隔离级别,可解决事务并发产生的问题,如脏读、不可重复读、虚读
· ISOLATION_DEFAULT
· ISOLATION_READ_UNCOMMITTED
· ISOLATION_READ_COMMITTED 可解决脏读
· ISOLATION_REPEATABLE_READ 可解决 不可重复读
· ISOLATION_SERIALIZABLE 全都能解决,但性能低,相当于锁表
2.2 事务传播行为 主要作用:解决 业务方法在调用业务方法时,它们之间事务统一性的问题
3 TransactionStatus
事务状态 事务具体的运行状态 平台对象操作事务行为,定义对象设置事务属性,状态对象反馈事务运行过程中的信息
7.2 基于XML的声明式事务控制
采用声明的方式来处理事务,即在配置文件中进行声明 Spring声明式事务控制底层即为AOP
需明确:
1 谁是切点?
2 谁是通知?
3 配置切面?
通过事务控制,是该方法内的accountDao的out和in方法执行统一,即不会发生 一个执行 另一个未执行
pom.xml配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
切点配置 平台事务管理器配置(如果Dao层的实现不是原生的JDBC,则配置需要更改)
通知事务增强配置
< tx:attributes >是用来设置事务的属性信息 < tx:method >代表切点方法的事务参数的配置
name:切点方法名称
isolation:事务的隔离级别
propogation:事务的传播行为
timeout:超时时间
read-only:是否只读
7.3 基于注解的声明式事务控制
自定义的Bean用注解,非自定义的Bean需要添加到xml配置文件中
切点增强 在方法上加 @Transactional( ) 如果注解使用在类上,则该类下的所有方法均使用同一套注解参数配置,如果方法、类上均存在注解,则就近原则生效
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/2626.html