国外创意设计网站,世界互联网公司排名,杭州网站建设品牌,张家界建设网站3、Spring Bean
Bean 代指的就是那些被 IoC 容器所管理的对象#xff0c;我们需要告诉 IoC 容器帮助我们管理哪些对象#xff0c;这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。
Bean的创建方式
1. XML 配置文件#xff1a; 传统上我们需要告诉 IoC 容器帮助我们管理哪些对象这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。
Bean的创建方式
1. XML 配置文件 传统上使用 XML 文件来定义和配置 beans。
2. 注解Annotation-based configuration 使用如 Component, Service, Repository, Controller 等注解来自动注册 bean。
3. Java 配置类Java-based configuration 使用 Configuration 和 Bean 注解来定义配置类和方法。将一个类声明为 Bean 的注解有哪些?
Component 通用的注解可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层可以使用Component 注解标注。Repository : 对应持久层即 Dao 层主要用于数据库相关操作。Service : 对应服务层主要涉及一些复杂的逻辑需要用到 Dao 层。Controller : 对应 Spring MVC 控制层主要用户接受用户请求并调用 Service 层返回数据给前端页面。
Component 和 Bean 的区别是什么
Component 注解作用于类而Bean注解作用于方法。Component 通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,Bean告诉了 Spring 这是某个类的实例当我需要用它的时候还给我。Bean 注解比 Component 注解的自定义性更强而且很多地方我们只能通过 Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring容器时则只能通过 Bean来实现。
Configuration
public class AppConfig {Beanpublic TransferService transferService() {return new TransferServiceImpl();}}Bean 的作用域有哪些?
singleton 单例 : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的是对单例设计模式的应用。
prototype 原型: 每次获取都会创建一个新的 bean 实例。也就是说连续 getBean() 两次得到的是不同的 Bean 实例。
request 请求仅 Web 应用可用: 每一次 HTTP 请求都会产生一个新的 bean请求 bean该 bean 仅在当前 HTTP request 内有效。
session 会话仅 Web 应用可用 : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean会话 bean该 bean 仅在当前 HTTP session 内有效。
## 配置作用域
xml 方式
bean id... class... scopesingleton/bean单例 Bean 的线程安全问题了解吗
大部分时候我们并没有在项目中使用多线程所以很少有人会关注这个问题。单例 Bean 存在线程问题主要是因为当多个线程操作同一个对象的时候是存在资源竞争的。
常见的有两种解决办法
在 Bean 中尽量避免定义可变的成员变量。在类中定义一个 ThreadLocal 成员变量将需要的可变成员变量保存在 ThreadLocal 中推荐的一种方式。
不过大部分 Bean 实际都是无状态没有实例变量的比如 Dao、Service这种情况下 Bean 是线程安全的。
4、Spring AoP
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关却为业务模块所共同调用的逻辑或责任例如事务处理、日志管理、权限控制等封装起来便于减少系统的重复代码降低模块间的耦合度并有利于未来的可拓展性和可维护性。 AOP组成结构 切面Aspect 一个关注点的模块化这个关注点可能会横切多个对象。切面可以包含通知和切点。 连接点Join Point 程序执行的某个特定位置如方法调用或异常抛出的地方。在 Spring AOP 中一个连接点总是表示一个方法的执行。 通知Advice 切面在特定连接点上执行的动作。主要有以下类型 前置通知Before advice在某连接点之前执行但不影响连接点的执行。后置通知After returning advice在某连接点正常完成后执行。异常通知After throwing advice在方法抛出异常退出时执行。最终通知After advice无论连接点退出的方式如何都将执行的通知。环绕通知Around advice围绕一个连接点的通知可以在方法调用前后自定义行为甚至可以完全替换方法。 切点Pointcut 匹配连接点的断言在 AOP 语法中通知与一个切点表达式关联并在满足切点的连接点上运行。 目标对象Target Object 被一个或多个切面所通知的对象。 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;Aspect
Component
public class LoggingAspect {// 定义切点匹配com.example.service包下所有类的所有方法Pointcut(execution(* com.example.service.*.*(..)))public void serviceLayer() {}// 前置通知在目标方法执行前调用Before(serviceLayer())public void logBefore(JoinPoint joinPoint) {System.out.println(前置通知即将执行方法: joinPoint.getSignature().getName());}// 后置通知在目标方法正常执行后调用AfterReturning(pointcut serviceLayer(), returning result)public void logAfterReturning(JoinPoint joinPoint, Object result) {System.out.println(后置通知方法执行完成: joinPoint.getSignature().getName() , 返回值 result);}// 异常通知在目标方法抛出异常后调用AfterThrowing(pointcut serviceLayer(), throwing error)public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {System.out.println(异常通知方法执行异常: joinPoint.getSignature().getName() , 异常信息 error.getMessage());}// 最终通知无论目标方法如何结束都会执行After(serviceLayer())public void logAfter(JoinPoint joinPoint) {System.out.println(最终通知无论方法如何执行完毕都会调用);}// 环绕通知可以在目标方法前后自定义行为也可以阻止方法的执行Around(serviceLayer())public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println(环绕通知开始方法名 joinPoint.getSignature().getName());try {Object result joinPoint.proceed();System.out.println(环绕通知成功结束结果是 result);return result;} catch (Throwable e) {System.out.println(环绕通知捕获到异常 e.getMessage());throw e; // 可以决定是否重新抛出异常} finally {System.out.println(环绕通知结束);}}
}Spring AOP 就是基于动态代理的如果要代理的对象实现了某个接口那么 Spring AOP 会使用 JDK Proxy去创建代理对象而对于没有实现接口的对象, Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理 术语含义目标(Target)被通知的对象代理(Proxy)向目标对象应用通知之后创建的代理对象连接点(JoinPoint)目标对象的所属类中定义的所有方法均为连接点切入点(Pointcut)被切面拦截 / 增强的连接点切入点一定是连接点连接点不一定是切入点通知(Advice)增强的逻辑 / 代码也即拦截到目标对象的连接点之后要做的事情切面(Aspect)切入点(Pointcut)通知(Advice)
Spring AOP 和 AspectJ AOP 有什么区别
Spring AOP 属于运行时增强而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying)而 AspectJ 基于字节码操作(Bytecode Manipulation)。如果我们的切面比较少那么两者性能差异不大。但是当切面太多的话最好选择 AspectJ 它比 Spring AOP 快很多。
AspectJ 定义的通知类型有哪些
Before前置通知目标对象的方法调用之前触发After 后置通知目标对象的方法调用之后触发AfterReturning返回通知目标对象的方法调用完成在返回结果值之后触发AfterThrowing异常通知 目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常则会有返回值如果方法抛出了异常则不会有返回值。Around 环绕通知编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种因为它可以直接拿到目标对象以及要执行的方法所以环绕通知可以任意的在目标对象的方法调用前后搞事甚至不调用目标对象的方法
多个切面的执行顺序如何控制
// 通常使用Order 注解直接定义切面顺序,值越小优先级越高
Order(3)
Component
Aspect
public class LoggingAspect implements Ordered {// 实现Ordered 接口重写 getOrder 方法
Component
Aspect
public class LoggingAspect implements Ordered {// ....Overridepublic int getOrder() {// 返回值越小优先级越高return 1;}
}