Spring IOC\AOP\Bean

Spring是一个轻量级的控制反转IOC和面向切面编程AOP的框架

Spring 自带 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、可以很方便地集成第三方组件(电子邮件,任务,调度,缓存等等)、对单元测试支持比较好、支持 RESTful Java 应用程序的开发。

ApplicationContext作为Spring容器,Bean在ApplicationContext容器中

 

1、控制反转IOC

是一种思想:两方之间不互相依赖,由第三方容器来管理相关资源。

ioc实现基础包:org.springframework.beansorg.springframework.context

(1)控制:对象创建、实例化、属性赋值、对象间关系管理的权利

(2)反转:控制权交由Spring框架、IOC容器,由这些容器来创建管理对象 例:Tomcat 创建servlet对象

(3)好处:对象之间解耦、降低依赖;资源容易管理

(4)实现方式:依赖注入(DI注入) 创建对象,给属性赋值

= DI注入的方式(可用xml配置文件 可用注解)

==1、构造注入

spring调用类的有参数构造方法 创建对象并完成赋值

==2、set注入(经常使用)

spring调用类的set方法 实现属性的赋值

==3、扩展方式注入(p命名空间、c命名空间)

p命名空间注入:可以直接注入属性的值property

c命名空间注入:构造器注入 construct-arg

导入约束xmlns:p="http://www.springframework.org/schema/p"
<!--p命名空间注入:可以直接注入属性的值 property-->
   <bean id="user" class="com.qifengle.pojo.User" p:name="禾下凉" p:age="22"/>

导入约束xmlns:c="http://www.springframework.org/schema/c"
<!--c命名空间注入:构造器注入 construct-arg-->
<bean id="admin" class="com.qifengle.pojo.Admin" c:aname="禾下凉" c:apwd="666"/>

 

2、面向切面编程AOP

是OOP(面向对象编程)的一种延续。

相比较OOP抽取出横切逻辑代码业务逻辑代码,根本上解耦,避免逻辑代码重复。

(1)基于动态代理(JDK动态代理 | CGLIB动态代理)

=当要代理的对象实现了某个接口,AOP会使用JDK Proxy;(必须实现接口)

=当要代理的对象没有实现接口,AOP会使用CGLIB Proxy 生成一个被代理对象的子类来作为代理(原理是继承)

(2)aop技术实现的框架

=Spring 属于运行时增强、基于动态代理

=AspectJ 属于编译时增强、基于字节码操作

     ==实现方式:1、使用XML的配置文件 配置全局事务

                           2、使用注解(一般的使用方式)

     ==使用:1、切面的执行时间(Advice) 用注解表示  @Before、@AfterReturning、@Around、@AfterThrowing、@After

                    2、切面执行位置 切入点表达式

切入点表达式:execution(访问权限 方法返回值 方法声明(参数) 异常裂隙)

execution(* set*(..)) 指定切入点为:任意一个以“set”开始的方法

execution(* com.qifenle.service..(..)):包.类.方法 指定切入点为:定义在service包里的任意类,每个类中的任意方法

=切面多的情况下,最好使用AspectJ ,功能更强大,更快

(3)面向切面编程 切面是什么?

非业务方法,给目标类增加的功能,独立使用的(如时间、事务功能、日志、权限验证等)

(4)切面的执行位置和执行时间

       =切面 Aspect 要增强的功能代码

       =连接点 JoinPoint 连接业务方法和切面的位置的方法

       =切入点 Poincut 多个连接点的集合 切面执行的位置

       =目标对象 给目标对象的方法增加功能 , 这个类就是目标对象

       =通知 Advice 表示切面功能执行的时间 目标方法执行前或后

 

3、spring Bean

(1)Bean: 指被ioc容器所管理的对象

(2)bean的作用域

      =1、singleton:单例bean实例 spring默认bean是单例的(单例模式的应用)

      =2、prototype: 每次请求都会创建一个新的bean实例

      =3、request: 每次HTTP请求都会产生一个新的bean,仅当前request请求周期内有效

      =4、session:每次新的session的HTTP请求都会产生一个新的bean,仅当前HTTP的session周期内有效

配置bean的作用域(xml方式)
<bean id="..." class="..." scope="singleton"></bean>
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
   return new Person();
}

(3)bean的三种装配方式

     =1、byName自动装配

   <!--    autowire="byName" 自动装配
      自动在容器中查找 对象对应的set方法set后面的值 对应的 bean id
      setCat ——》 id="cat"
      setDog ——》 id="dog"
-->
  <bean id="people" class="com.qifengle.pojo.People" autowire="byName">
      <property name="name" value="禾下凉"/>
  </bean>

    =2、byType自动装配

  <!--      autowire="byType"  自动装配
      自动在容器中查找 对象属性类型相同的 bean 但有唯一性  
      class="com.qifengle.pojo.Cat" ——》 id="cat" 可以不用id=“cat” <bean class="com.qifengle.pojo.Cat"/>
      class="com.qifengle.pojo.Dog" ——》 id="dog" 可以不用id=“dog” <bean class="com.qifengle.pojo.Dog"/>
      class="com.qifengle.pojo.Dog" ——》 id="dog1" 只有一个Dog属性类型 但对应两个id 则报错
-->
 <bean id="people" class="com.qifengle.pojo.People" autowire="byType">
     <property name="name" value="禾下凉"/>
 </bean>

    =3、自动装配注解

@Autowired 通过byType再通过byname的方式实现,而且必须要求这个对象存在 有时需要@Qualifier(value="id")指定id

@Resource默认通过byName的方式实现,如果通过byName实现不了 则通过byType实现 两个都实现不了则报错

(4)注解的区别:

声明一个类为Bean的注解有:

@Autowired 自动装配

@Component 通用的注解,可将任意类作为bean交由spring管理

@Repository 持久层注解 Dao|Mapper层 主要用于数据库相关操作

@Service 服务层注解 逻辑代码操作

@Controller 控制层操作 主要用于用户请求和接收Service层返回的数据给前端

    =1、@Component 作用于类,放在类上说明这个类被spring容器管理了

通过类路径扫码自动装配到spring的bean容器中

   =2、@ComponentScan 作用于类

可以自定义要扫描的路径

   =3、@Bean 作用于方法

标注在方法上,将该实例装配到spring的bean容器中

比@Component自定义性更强,第三方类库的类装配到spring容器中经常使用

   =4、@Value 作用在set方法或属性上

@Value("禾下凉")//相当于<property name="name" value="禾下凉"/>

(2)bean的生命周期

  =1、实例化bean对象

  =2、设置对象属性 利用set()方法设置

  =3、实现检查*Aware接口,若实现便调用相关的set方法,传入相关的对象实例。例:

     ==实现了BeanNameAware接口,调用setBeanName(),传入Bean的名字

     ==实现了BeanClassLoaderAware接口,调用setBeanClassLoader(),传入ClassLoader对象实例

     ==实现了BeanFactoryAware接口,调用setBeanFactory(),传入BeanFactory对象实例

  =4、BeanPostProcessor对象前置处理,执行postProcessBeforeInitialization()方法

  =5、检查是否实现InitializingBean即可,有就调用afterPropertiesSet()方法

  =6、检查是否配置有包含自定义init-method属性,有,执行指定方法

  =7、BeanPostProcessor对象后置处理,执行postProcessAfterInitialization()方法

  =8、Bean使用阶段

  =9、销毁Bean,如果bean实现了DisposableBean接口,执行destroy()方法

  =10、销毁Bean,如果配置文件中有定义包含destroy-method属性,执行指定方法

posted @ 2022-04-14 23:06  与长安故里  阅读(48)  评论(0编辑  收藏  举报