Spring IOC和AOP理解,以及怎么解决循环依赖
2020-04-04 16:05:03来源:博客园 阅读 ()
- IOC
IOC,控制反转(Inversion of Control),就是把对象的创建(即bean的new操作),交给Spring来实现。
通过XML配置:bean标签是用于配置被spring容器管理的bean信息,我们可以通过bean标签,完成IOC的配置。
- 使用默认无参构造函数来创建类对象,并存入spring容器
<bean id="userService" class="com.xcj.spring.service.UserServiceImpl"></bean>
public class UserServiceImpl implements UserService { }
- 静态工厂方式
<!-- 使用StaticFactory类中的静态方法createDemoService创建对象,并存入spring容器(简单了解下,实际中基本不用) --> <bean id="demoService" class="com.xcj.spring.factory.StaticFactory" factory-method="createDemoService"></bean>
public class StaticFactory { public static DemoService createDemoService() { return new DemoServiceImpl(); } }
public class DemoServiceImpl implements DemoService { }
- 实例工厂方式
<!-- 先把工厂的创建交给spring来管理,再在使用工厂的bean来调用里面的方法 --> <bean id="instanceFactory" class="com.xcj.spring.factory.InstanceFactory"></bean> <bean id="beanService" factory-bean="instanceFactory" factory-method="createBeanService"></bean>
public class InstanceFactory { public static BeanService createBeanService() { return new BeanServiceImpl(); } }
public class BeanServiceImpl implements BeanService { }
DI,依赖注入(Dependency Injection),是spring IOC的具体实现,做的工作是Spring实例化bean对象后,对bean对象的属性信息进行赋值的操作。
依赖指的是bean实例中的属性,分为简单类型(8种基本类型和String类型)的属性、POJO类型的属性、集合数组类型的属性。
注入方式:构造器,set方法,注解,(还有使用p名称空间注入数据,本质上还是调用set方法)。
- 构造器注入
<bean id="userDemoService" class="com.xcj.spring.service.UserDemoServiceImpl"> <constructor-arg name="id" value="1"></constructor-arg> <constructor-arg name="name" value="zhangsan"></constructor-arg> </bean>
public class UserDemoServiceImpl implements UserDemoService { private int id; private String name; public UserDemoServiceImpl(int id, String name) { this.id = id; this.name = name; } }
- set方法注入(手动装配,即XML方式)
<bean id="demoSetService" class="com.xcj.spring.service.DemoSetServiceImpl"> <!-- List类型的属性 --> <property name="lists"> <list> <value>11</value> <value>22</value> </list> </property> <!-- Set类型的属性 --> <property name="sets"> <set> <value>111</value> <value>222</value> </set> </property> <!-- Map类型的属性 --> <property name="maps"> <map> <entry key="111" value="111-01"/> <entry key="222" value="222-01"/> </map> </property> <!-- Properties类型 --> <property name="props"> <props> <prop key="name">root</prop> <prop key="password">123456</prop> </props> </property> </bean>
public class DemoSetServiceImpl implements DemoSetService { private List<Object> lists; private Set<Object> sets; private Map<String, Object> maps; private Properties props; public void setLists(List<Object> lists) { this.lists = lists; } public void setSets(Set<Object> sets) { this.sets = sets; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public void setProps(Properties props) { this.props = props; } }
- 注解(自动装配)
(1)@Autowired,按类型注入,要唯一;如果遇到相同的,则要加上@Qualifer,表示在类型注入基础上按名称注入。
(2)@Resource,按照bean的name/id注入。
@Service("userService") public class UserServiceImpl implements UserSetService{ @Autowired private UserDao userDao; }
那么问题:Spring怎么解决循环依赖的?通过三级缓存。
- AOP
AOP,面向切面编程(Aspect Oriented Programming),是一种编程范式,是OOP(面向对象编程)的延续,采用横向抽取机制,补充了OOP纵向继承体系无法解决的重复代码优化方式。
譬如,假设有A,B有相同的逻辑,我们可以横向抽取相同的部分出来,通过AOP思想和业务串联起来,同时这是可插拔式的。
AOP思想的实现一般都是基于代理模式,给业务代码进行功能增强,将业务代码和系统代码解耦。
如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;
如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类。
(1)使用XML方式实现
public class AopAdvice { public void saveLog() { System.out.println("保存日志"); } }
<bean name="aopAdvice" class="com.xcj.spring.advice.AopAdvice"></bean> <aop:config> <aop:aspect ref="aopAdvice"> <aop:before method="saveLog" pointcut="execution(* com.xcj.spring..*Service.do*(..))" /> </aop:aspect> </aop:config>
(2)使用注解实现
@Component("aopDemoAdvice") @Aspect public class AopDemoAdvice { @Before(value="execution(* com.xcj.spring..*Service.do*(..))") public void saveLog() { System.out.println("保存日志"); } }
<!-- Spring AOP,通过动态代理技术实现的,而动态代理是基于反射 --> <!-- 开启注解并扫描指定包中带有注解的类 --> <context:component-scan base-package="com.xcj.spring.service"></context:component-scan> <!-- 开启AOP自动代理 --> <aop:aspectj-autoproxy />
TODO
原文链接:https://www.cnblogs.com/scorpio-cat/p/12632063.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇: LeetCode 42. 接雨水
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash