Spring随手笔记

Bean的作用域

===============

scope属性来设置

singleton 单例 创建容器时,对象就被创建

prototype 多例 当嗲用getBean()方法实例化bean,使用了才创建,也叫原型模式

request web项目中,存在request中

session web项目中,存在session中

global session web项目中,portlet环境中,如果没有这个环境,则相当于session

Bean的生命周期配置

init-method:指定类中的初始化方法名称

destory-method:指定类中销毁方法的名称

Bean实例化的三种方式

  • 无参构造方法

  • 工厂静态方法

  • 工厂实例方法

bean的依赖注入(DI)的概念,他是Spring框架核心IOC的具体实现

在编写程序时,通过控制反转,把对象的创建交给Spring,

Bean的依赖注入方式

  • 构造方法

  • set方法

属性注入的方式为name属性名称value注入的普通属性值ref注入的对象引用值

标签,构造方法

applicationContext:接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象

ApplicationContext 继承自 BeanFactory

正常的写法

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService =(UserService)applicationContext.getBean("userService");UserService userService2=applicationContext.getBean(UserService.class)
复制代码

常见注解:

@compoent 使用在类上实例化Bean

@Controller 使用在web层类上用于实例化Bean

@Service 使用在Service层上实例化Bean

@Repository 使用在dao层上实例化Bean

@Autowired 使用在字段上根据类型依赖注入

@Qualifier

Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的;​@Autowired默认按照类型匹配注入bean,如果有多个实现类,搭配@Qualifier(“实现类名称”)表明注入的是哪一个实现类的bean:比如:@Autowired@Qualifier(“TestServiceImpl1”)private TestService testService; //注入的就是TestServiceImpl1这个实现类,注意如果该实现类使用了诸如@Service(“beanName”)这种注解,那么TestServiceImpl1就是beanName;​而@Resource默认按照名称匹配注入bean,而且可以使用name作为属性来确定实际注入的bean比如:@Resource(name = “TestServiceImpl1”)private TestService testService;
复制代码

@Resource 相当于@Autowired+@Qualifier,按照名称进行注入

@Value 注入普通属性

@Scope 标注bean的作用范围

@Configuration 指定当前类是一个配置类

@ComponentScan 初始化容器时要扫描的包

@Bean 使用在方法上,标注该方法的返回值存储到Spring容器中

@Import 用于导入其他配置类

Spring AOP

AOP意为面向切面编程

  • 在不修改源码的情况下进行功能增强

  • 减少重复代码,提高开发效率,并且便于维护

Aop的底层设计spring提供的动态代理技术实现的,生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强

上机实践下声明式事务配置和AOP的一些简单使用

SpringMvc

1.首先会请求到前端控制器 DispatcherServlet

2.请求查询handler,处理器映射器HandelMapping返回处理器的执行链HandlerExecution,返回给前端控制器

3.会去处理器适配器HandlerAdaptor,发送请求执行的Handler,返回ModelAndView

4.DispatcherServlet会请求视图解析器,给视图解析器ViewResolver,返回视图View对象,渲染视图。

简单来说:一个请求路由到达前端控制器,前端控制器把这个Handler发给处理器映射器HandelMapping,请求查询Handler,处理器映射器HandlerMapper,返回一个处理结果HandlerExecution,请求执行Handler,会到处理器适配器HandlerAdaptor查询,返回一个ModelAndView进行查询,前端控制器拿到这个结果,会去视图解析器里面进行查找,返回View对象,然后在去渲染

SpringMvc注解

@RequestMapping

@ResponseBody

向request域中存储数据

modelAndView.setAttribute()

modelAndView.addObject()

回写数据

response.getWriter().print("Hello world")

直接返回字符串

@ResponseBody 指的是将需要回写的字符串直接返回

@RequestParam value required defaultValue

Restful风格

文件上传客户端三要素,enctype属性是多部分表单形式

SpringMvc中所有的Dao Service Controller都会向上抛出异常,最后由HandlerExceptionResolver异常处理器

学习spring最重要的两个点是声明式事务的配置和aop的使用

下面来看两个例子

先来AOP的实现的小例子吧

1.引入依赖

<!--Spring AOP--><dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version></dependency>​
复制代码

2.添加spring.xml的配置

xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
复制代码

两种方式实现

方式1:注解实现

/*** 切⾯* 切⼊点和通知的抽象 (与⾯向对象中的 类 相似)* 定义 切⼊点和通知 (切⼊点定义了要拦截哪些类的哪些⽅法,通知则定义了拦截过⽅法后要做什么)*/@Component // 将对象交给IOC容器去实例化@Aspect // 声明当前类是⼀个切⾯public class LogCut { /** * 切⼊点: * 匹配规则。规定什么⽅法被拦截、需要处理什么⽅法 * 定义切⼊点 * @Pointcut("匹配规则") * * Aop 切⼊点表达式简介 * 1. 执⾏任意公共⽅法: * execution(public *(..)) * 2. 执⾏任意的set⽅法 * execution(* set*(..)) * 3. 执⾏com.xxxx.service包下任意类的任意⽅法 * execution(* com.xxxx.service.*.*(..))* 4. 执⾏com.xxxx.service 包 以及⼦包下任意类的任意⽅法 * execution(* com.xxxx.service..*.*(..)) * * 注:表达式中的第⼀个* 代表的是⽅法的修饰范围 * 可选值:private、protected、public (* 表示所有范围) */ @Pointcut("execution (* com.xxxx.service..*.*(..) )") public void cut(){} /** * 声明前置通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法执⾏前 执⾏该通知 * */ @Before(value = "cut()") public void before() { System.out.println("前置通知....."); } /** * 声明返回通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法(⽆异常)执⾏后 执⾏该通知 * */ @AfterReturning(value = "cut()") public void afterReturn() { System.out.println("返回通知....."); } /** * 声明最终通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法(⽆异常或有异常)执⾏后 执⾏该通知 * */ @After(value = "cut()") public void after() { System.out.println("最终通知....."); } /** * 声明异常通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法出现异常时 执⾏该通知 */ @AfterThrowing(value="cut()",throwing = "e") public void afterThrow(Exception e) { System.out.println("异常通知....." + " 异常原因:" + e.getCause()); } /** * 声明环绕通知 并将通知应⽤到切⼊点上 * ⽅法执⾏前后 通过环绕通知定义相应处理 * 需要通过显式调⽤对应的⽅法,否则⽆法访问指定⽅法 (pjp.proceed();)* @param pjp * @return */ @Around(value = "cut()") public Object around(ProceedingJoinPoint pjp) { System.out.println("前置通知..."); Object object = null; try { object = pjp.proceed(); System.out.println(pjp.getTarget() + "======" + pjp.getSignature()); // System.out.println("返回通知..."); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("异常通知..."); } System.out.println("最终通知..."); return object; }}配置文件spring.xml<!--配置AOP代理--><aop:aspectj-autoproxy/>
复制代码

xml实现

*** 切⾯* 切⼊点和通知的抽象 (与⾯向对象中的 类 相似)* 定义 切⼊点和通知 (切⼊点定义了要拦截哪些类的哪些⽅法,通知则定义了拦截过⽅法后要做什么)*/@Component // 将对象交给IOC容器去实例化public class LogCut02 { public void cut(){} /** * 声明前置通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法执⾏前 执⾏该通知 */public void before() { System.out.println("前置通知....."); } /** * 声明返回通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法(⽆异常)执⾏后 执⾏该通知 * */ public void afterReturn() { System.out.println("返回通知....."); } /** * 声明最终通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法(⽆异常或有异常)执⾏后 执⾏该通知 * */ public void after() { System.out.println("最终通知....."); } /** * 声明异常通知 并将通知应⽤到定义的切⼊点上 * ⽬标类⽅法出现异常时 执⾏该通知 */ public void afterThrow(Exception e) { System.out.println("异常通知....." + " 异常原因:" + e.getCause()); } /** * 声明环绕通知 并将通知应⽤到切⼊点上 * ⽅法执⾏前后 通过环绕通知定义相应处理 * 需要通过显式调⽤对应的⽅法,否则⽆法访问指定⽅法 (pjp.proceed();) * @param pjp * @return */ public Object around(ProceedingJoinPoint pjp) { System.out.println("前置通知..."); Object object = null; try { object = pjp.proceed(); System.out.println(pjp.getTarget() + "======" + pjp.getSignature()); // System.out.println("返回通知..."); } catch (Throwable throwable) {throwable.printStackTrace(); System.out.println("异常通知..."); } System.out.println("最终通知..."); return object; }}​​<!--aop相关配置--><aop:config> <!--aop切⾯--> <aop:aspect ref="logCut02"> <!-- 定义aop 切⼊点 --> <aop:pointcut id="cut" expression="execution(* com.xxxx.service..*.*(..))"/> <!-- 配置前置通知 指定前置通知⽅法名 并引⽤切⼊点定义 --> <aop:before method="before" pointcut-ref="cut"/> <!-- 配置返回通知 指定返回通知⽅法名 并引⽤切⼊点定义 --> <aop:after-returning method="afterReturn" pointcut-ref="cut"/> <!-- 配置异常通知 指定异常通知⽅法名 并引⽤切⼊点定义 --> <aop:after-throwing method="afterThrow" throwing="e" pointcut-ref="cut"/> <!-- 配置最终通知 指定最终通知⽅法名 并引⽤切⼊点定义 --> <aop:after method="after" pointcut-ref="cut"/> <!-- 配置环绕通知 指定环绕通知⽅法名 并引⽤切⼊点定义 --> <aop:around method="around" pointcut-ref="cut"/> </aop:aspect></aop:config>​
复制代码

spring中声明式事务的配置

声明式事务实现的例子

​//我们想使之支持事务的服务层接口 package x.y.service; public interface FooService {     Foo getFoo(String fooName);     Foo getFoo(String fooName, String barName);     void insertFoo(Foo foo);     void updateFoo(Foo foo);}

​//上面接口的一个实现 package x.y.service; public class DefaultFooService implements FooService {     public Foo getFoo(String fooName) {        throw new UnsupportedOperationException();    }     public Foo getFoo(String fooName, String barName) {        throw new UnsupportedOperationException();    }     public void insertFoo(Foo foo) {        throw new UnsupportedOperationException();    }     public void updateFoo(Foo foo) {        throw new UnsupportedOperationException();    } }

<!-- 来自文件 'context.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
 
    <!-- 这是我们希望使之支持事务的服务层对象 -->
    <bean id="fooService" class="x.y.service.DefaultFooService"/>
 
    <!-- 事务化配置(请看下面的<aop:advisor/>) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- 事务语义... -->
        <tx:attributes>
            <!-- 所有用'get'开头的方法都是只读的 -->
            <tx:method name="get*" read-only="true"/>
            <!-- 其他的方法使用默认的事务配置(看下面) -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
 
    <!-- 使得上面的事务配置对FooService接口的所有操作有效 -->
    <aop:config>
        <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
    </aop:config>
 
    <!-- 不要忘了DataSource -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
        <property name="username" value="scott"/>
        <property name="password" value="tiger"/>
    </bean>
 
    <!-- 同样的, 也不要忘了PlatformTransactionManager -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 关于其他的<bean/>的定义 -->
</beans>

<aop:config>
    <aop:pointcut id="fooServiceMethods" expression="execution(* x.y.service.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceMethods"/>
</aop:config>



<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
    <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
复制代码

猜你喜欢

转载自juejin.im/post/7040430613685338120
今日推荐