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>
复制代码