Spring的简单使用

3 篇文章 0 订阅

Spring的简单使用

三层架构

三层架构作用
表现层(Web)接收请求,向客户端响应结果
业务层(Service)负责业务逻辑处理
持久层(Dao)与数据库交互,对数据库表进行增删改查

CRUD

Create 添加数据	---> insert语句
Read 读取数据	---> select语句
Update 修改数据	---> update语句
Delete 删除数据	---> delete语句

Spring IOC容器

  • 配置在 /resources/bean.xml

头文件

<?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">

实体类User

class User{
 String name;
 Integer age;
 public void init(){};
 public void destroy(){};
}
    <!--创建User对象: User user = new User();-->
    <!--
       bean 表示要创建的对象
         id 对应的引用名称
         class 表示对象的全路径
    -->
    <bean id="user" class="com.osc.entity.User"/>
</beans>

等价于

User user = new User();
实例化的更多属性
属性说明
id对象的引用名称;唯一性
name对象的引用名称; 与id区别是:name一次可以定义多个引用名称。
class类的类路径
scope设置bean的作用范围。
--------------------------------
singleton:单例。默认值
prototype:多例
request:web项目中,将对象存入request域中
session:web项目中,将对象存入session域中
globalsession:web项目中,应用在集群环境, 如果没有集群,环境,相当于session
init-method指定类中初始化方法的名称,在构造方法执行完毕后立即执行
destroy-method指定类中销毁方法名称,在销毁spring容器前执行
lazy-init设置为true表示延迟创建对象,即在第一次使用对象时候才创建单例 的对象,只对单例对象有效。
<bean
      id="user2"
      name="user3,user4" 		
      class="com.osc.entity.User"
      scope="prototype"
      lazy-init="true"
      init-method="init"
      destroy-method="destroy"/>
注入值
<!--
  注入值
	<constructor-arg> : 构造方法的注入
  index:参数列表的索引
  name:实体类的成员变量名
  type:成员变量的类型
  value:注入的值
	<property> : set方法的注入
  id:set变量名的方法
  value:注入的值
 -->
<bean id="user" class="com.osc.entity.User">
    <constructor-arg index="0" name="name" 
                     type="String" value="我是名字"/>
    <constructor-arg index="1" name="age" 
                     type="int" value="100"/>
    <property name="age" value="168"/>
</bean>

等价于

User user = new User("我是名字",100);
user.setAge(168); 
bean引用
<bean id="str_name" class="java.lang.String">
    <constructor-arg value="Jack"/>
</bean>

<bean id="user" class="com.osc.entity.User">
    <property name="name" ref="str_name"/>
</bean>

等价于

String str_name = new String("Jack");
User user = new User();
user.setName(str_name);


Spring IOC创建Druid连接池

利用容器实例对象

利用注解扫描开启实例对象

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="url" 
              value="jdbc:mysql://url/database?characterEncoding=utf8"></property>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
    <property name="initialSize" value="3"></property>
    <property name="maxActive" value="10"></property>
</bean>

等价于

DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://url/database?characterEncoding=utf8");
dataSource.setUserName("root");
...

利用容器创建JDBCTemplate对象+Dao+Service

<!--2.创建JdbcTemplate,注入连接池-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--3.创建dao,注入JdbcTemplate对象-->
<bean id="dao" class="com.osc.dao.impl.AccountDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

<!--4.创建service,注入dao-->
<bean id="service" class="com.osc.service.impl.AccountServiceImpl">
    <property name="accountDao" ref="accountDao"></property>
</bean>

等价于

// 2.创建JdbcTemplate,注入连接池
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 3.创建dao,注入JdbcTemplate对象
AccountDaoImpl dao = new AccountDaoImpl();
dao.setJdbcTemplate(jdbcTemplate);
// 4.创建service,注入dao
AccountServiceImpl service = new AccountServiceImpl();
service.setAccountDao(dao);

注解开发

@Component

在java类上使用这个注解相当于在bean.xml创建了一个类,默认创建的id是首指母小写的类名

public class OscBean{}  -->  <bean id="oscBean" class="com.osc.OscBean">...</bean>
@Controller

一般用于表现层的注解。

@Service

一般用于业务层的注解。

@Repository

一般用于持久层的注解。

都是和@Component作用完全一样,只是一个别名便于分别

@Autowired
  • 用来注入数据
  • 根据@Autowired修饰的字段类型,去容器中找对象注入进来
  • 可以省去set方法
  • 容器如有多个符合时根据bean的id注入
@Autowired
String name;
<bean id="str" class="java.lang.String">
    <constructor-arg value="osc"/>
</bean>

<bean id="name" class="java.lang.String">
    <constructor-arg value="zzy"/>
</bean>

例如上述情况:@Autowired类型为String,容器有2个bean符合注入,此时会以id识别注入,找不到就报错

name : "zzy"

开启注解扫描
  • 配置在bean.xml
  • 开启注解扫描:扫描com.osc.domain包下的注解
  • base-package指定要扫描的包下所有的类以及当然包下所有的子包下所有的类,如果要扫描多个包用逗号隔开
<context:component-scan base-package="com.osc.domain"></context:component-scan>
@Bean
  • @Bean和@Component的目的都是告知Spring要为这个类创建bean,但是Bean比Component的自定义性更强
  • @Bean只能用在方法上,返回的对象会创建到bean容器中
@PropertySource
  • 用于加载.properties文件数据
  • 加载类路径osc.properties文件
@PropertySource("classpath:osc.properties")
class User{}
@Value

依赖于@PropertySource使用,用于取properties文件里的值

osc.properties

name=osc
age=18
@PropertySource("classpath:osc.properties")
class User{
    @Value("${name}")	//取到osc.properties中键name对应的值
    String name;	//osc
    @Bean
    public User createUser(){
        User user = new User();
        user.setName(name);
        return user;	//会在容器创建这个User对象,id=user
    }
}

AOP切面编程

准备一个实现类或者普通类

public class SerImpl implements IService {
    @Override
    public void save() {
        System.out.println("保存账号!");
    }
}

创建一个日志记录类

public class Logger {
    public void printLog(){
        System.out.println("记录用户操作日志。");
    }
}

基于xml的AOP配置

标签名作用
aop:config声明aop配置
aop:aspect配置切面
-id给切面取一个唯一标识的名称
-ref引用日志类bean的id
aop:pointcut配置切入点表达式
-id给切入点取一个表达式唯一标识的名称
-expression指定切入点表达式
访问修饰符 返回值 包名称.类名称.方法名称(参数列表)
aop:before配置前置通知
-method指定通知方法的名称
-pointcut-ref指定切入点表达式(aop:pointcut)的id
<!--配置客户service-->
<bean id="serImpl" class="om.osc.SerImpl"></bean>

<!--配置日志通知advice-->
<bean id="logAdvice" class="com.itheima.utils.Logger"></bean>

<aop:config>
     <aop:aspect id="logAspect" ref="logAdvice">
         <aop:pointcut id="pt"
                       expression="execution(public void com.osc.SerImpl.save())">			 </aop:pointcut>
         <aop:before method="printLog" pointcut-ref="pt"></aop:before>
     </aop:aspect>
</aop:config>

切入点表达式

  • 访问修饰符 返回值 包名称.类名称.方法名称(参数列表)

访问修饰符可以省略

*****:统配一个包名或者类名或者方法名

:表示当前包及其子包

全匹配方式

public void com.itheima.service.impl.UserServiceImpl.save()

访问修饰符可以省略

public com.itheima.service.impl.UserServiceImpl.save()

包名和修饰符都可以使用* (有多少个包使用多少个*)

* *.*.*.*.UserServiceImpl.save()

包名中使用…,表示当前包及其子包

* com..*.UserServiceImpl.save()

类名和方法名也可以使用*

* com..*.*.save()
* com..*.*.*()
* com..*.*Impl.*av*()

参数列表也可以使用*和…

//参数任意,用*必须带有参数
* com..*.*.save(*)
//参数任意,用..参数可有可无
* com..*.*.save(..)

其他写法

//表示容器中以Service结尾的所有类匹配
bean(*Service)

通知类型

l 前置通知:在目标方法执行前执行

l 后置通知:在目标方法正常返回后执行。它和异常通知只能执行一个

l 异常通知:在目标方法发生异常后执行。它和后置通知只能执行一个

l 最终通知:无论目标方法正常返回,还是发生异常都会执行

l 环绕通知:综合了前面四类通知,可以手动控制通知的执行时间点和顺序

修改日志通知类

public class Logger {
    public void beforeNif(){}
    public void afterNif(){}
    public void throwNif(){}
    public void finalNif(){}
}

<aop:config>
    <aop:aspect ref="logger">
        <!--切入点表达式-->
        <aop:pointcut id="pt" expression="execution(* com..*.*(..))"/>
        <!--【前置通知】-->
        <aop:before method="beforeNif" pointcut-ref="pt"/>
        <!--【后置通知】-->
        <aop:after-returning method="afterNif" pointcut-ref="pt"/>
        <!--【异常通知】-->
        <aop:after-throwing method="throwNif" pointcut-ref="pt"/>
        <!--【最终通知】-->
        <aop:after method="finalNif" pointcut-ref="pt"/>
    </aop:aspect>
</aop:config>


事务控制

配置均在bean.xml中

创建事务管理器

<bean id="transactionManager" 
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- 引用jdbc连接数据库的数据源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>

配置事务通知规则

标签/属性作用
tx:advice事务通知规则配置
-transaction-manager引用的事务管理器
tx:attributes事务应用规则配置
-tx:method对指定的方法,如何管理事务
-name表示方法名
-read-only是否只读,默认false
-propagation默认值表示当前执行的方法必须有事务环境
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!--find/query/select/search
			开头的方法,都是只读事务,事务传播行为(有事务支持,没有也可以)-->
        <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="search*" read-only="true" propagation="SUPPORTS"/>
        <!--除了上面的方法,其他的所有方法都是读写事务,传播行为(必须有事务环境)-->
        <tx:method name="*" read-only="false" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

AOP配置

<aop:config>
    <aop:pointcut id="pt" expression="execution(* com.osc.service.impl.*.*(..))"/>
    <!--配置切入点表达式与通知的关联-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
</aop:config>

注解开启事务

事务属性
readOnly = false 默认值,读写事务,可以进行CRUD操作
propagation = Propagation.REQUIRED 默认值表示当前执行的方法必须有事务环

<!--4.2 开启Spring声明式事务的注解支持(就可以使用@Transactional注解)-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

@Service
//都是默认值,可以简写为@Transactional
@Transactional(readOnly = false,propagation = Propagation.REQUIRED)
public class UserServiceImpl implements IUserService {}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值