本文主要说明Spring主要解决什么问题,有哪些部分组成(这篇博客主要讲IOC以及AOP)
Sping是当代流行的一种开发方式,在Spring中包含了很多的框架,并且对其包含的框架进行了资源整合是的开发更加的简洁和集中。 Spring其本身相当于一个容器,而在这个容器中装的东西主是对象,Spring通过对控制容器来实现业务操作
IoC容器: spring-beans : ioc 实现,配置文件的访问、创建和管理 spring-core: 核心工具包 spring-context:封装IOC容器,提供扩展功能 SpEL : spring的表达式支持
基础服务: AOP : 面向切面编程支持 Aspects: 对AspectJ框架的支持 instrumentation: 字节码操作 messaging : 对消息服务的支持
功能: transactions : 事务支持 JDBC : spring对JDBC的封装 ORM : spring对于ORM框架的支持 web : 对于web开发的支持 在Spring中最重要的两个部分是IOC和AOP。
IOC主要做的是控制反转(inversion of control)即将控制权从调用的类转换成Spring容器,由Spring进行实例化对象和依赖注入。 在使用时需要对其配置配置文件;在工程中创建SpringConfig.xml文件
在java中调用的方法
//java中使用(jar包导入org.springframework:spring-context:5.2.0.RELEASE) //创建一个Spring ApplicationContext ac = new ClassPathXmlApplicationContext("springXml配置文件名"); //从容器中获取一个实例 Bean bean = ac.getBean("bean的ID名", Bean(Bean为实例类类名).class);注解
注册springbean(加在类名上):@Controller(“bean的ID名,不加为类名(第一个字母小写)”)@Service(“bean的ID名,不加为类名(第一个字母小写)”)@Component(“bean的ID名,不加为类名(第一个字母小写)”)@Repository(“bean的ID名,不加为类名(第一个字母小写)”)自动依赖注入:@Autowired:加在属性上@Value(“具体值”):加在基本数据类型属性上生命周期@PostConstruct:加在方法上为bean创建时执行的方法@PreDestroy:加在方法上为bean销毁时执行的方法作用域范围@Scope ("作用域") prototype 原型(每次创建一个实例)、singleton(默认) 单例(一个bean一个实例)、request 一次请求一个实例、session 一次会话一个实例、websocket 一次websocket链接一个实例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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--指定扫描的范围,包括递归的所有的包和子类--> <context:component-scan base-package="com.woniuxy.spring"/> </beans>在java中调用的方法
//java中使用(jar包导入org.springframework:spring-context:5.2.0.RELEASE) //创建一个Spring ApplicationContext ac = new ClassPathXmlApplicationContext("springXml配置文件名"); //从容器中获取一个实例 Bean bean = ac.getBean("bean的ID名", Bean(Bean为实例类类名).class);注解: @Bean @Configuration
@Configuration 标记一个类为配置类@Bean 标记某个方法返回值为spring的bean,方法参数为依赖注入的请求扫描
@Configuration 标记一个类为配置类 等价于一个SpringConfig.xml配置文件
@ComponentScan("被扫描包的路径") 打开包扫描功能,并且指定扫描的包 等价于 <context:component-scan base-package=“xxx”> 其他注解等同于使用注解式配置 在java中调用的方法
//java中使用(jar包导入org.springframework:spring-context:5.2.0.RELEASE) //创建一个Spring ApplicationContext ac = new AnnotationConfigApplicationContext("@Configuration标记的类的类名.class "); //从容器中获取一个实例 Bean bean = ac.getBean("bean的ID名", Bean(Bean为实例类类名).class);IOC实例化的方式 静态工厂bean实例化
<bean id="id名" factory-method="获取bean实例的静态方法" class="静态工厂类的全路径" />工厂bean实例化
<bean id="ID名" factory-bean="工厂beanID名" factory-method="工厂bean获取实例方法" />Spring的FactoryBean接口实例化
<bean id="id名" class="Spring工厂类的全路径"/> public class CarFactory implements FactoryBean<Car> { @Override public Car getObject() throws Exception { return new Car(); } @Override public Class<?> getObjectType() { return Car.class; } }IOC依赖注入方式 setter注入
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="id名" class="类的全路径"/> <bean id="id名" class="类的全路径"> <property name="set方法变量名" ref="bean的ID名"/> <property name="set方法变量名(变量为基本变量)" value="变量值"/> <property name="set方法变量名(变量为集合)"> <list> <!--list为基本数据类型--> <value>list内部的值</value> <!--list为对象时--> <ref bean="id名"/> </list> </property> <property name="set方法变量名(变量为集合)"> <map> <entry key="key值" value="value值"/> </map> </property> </bean> </beans>构造器注入
<bean id="id名" class="类的全路径"> <constructor-arg name="参数名" ref="值"></constructor-arg> <constructor-arg index="下标数" value="值"></constructor-arg> <constructor-arg name="参数名"> <list> <!--list为基本数据类型--> <value>list内部的值</value> <!--list为对象时--> <ref bean="id名"/> </list> </constructor-arg> </bean>IOC中配置的bean其作用域以及生命周期 prototype 原型(每次创建一个实例)
<bean id="getc" class="dao.GotConnection" scope="prototype"/> singleton(默认) 单例(一个bean一个实例)
<bean id="getc" class="dao.GotConnection" scope="singleton"/> request 一次请求一个实例
<bean id="getc" class="dao.GotConnection" scope="request "/> session 一次会话一个实例
<bean id="getc" class="dao.GotConnection" scope="session "/>websocket 一次websocket链接一个实例
<bean id="getc" class="dao.GotConnection" scope="websocket "/>bean的声明周期
在bean配置上写init-method(创建) destroy-method(销毁): init-method与destroy-method中配置的是创建时和销毁时需要调用额方法
<bean id="getUser" init-method="a" destroy-method="b" class="serverce.Userfactory"/> 实现InitializingBean和 DisposableBean
import org.springframework.beans.factory.InitializingBean; public class ccs implements InitializingBean , DisposableBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("kkkkksss"); } @Override public void destroy() throws Exception { System.out.println("ennnnnd"); } }IOC的优势:
解耦合,类与类之间的耦合度降低;提升代码的灵活性,可维护性AOP是Spring基于IOC对于OOP的拓展和补充 AOP将应用系统拆分为单个部分:核心业务逻辑及横向的通用逻辑。 AOP应用系统功能:大多为公共的,在很多的地方都会出现的功能如;打印日志、性能监控、事务管理、安全验证等。 AOP的一些名词
连接点 JoinPoint 需要加入功能的位置,方法切入点 PointCut 真正执行加入功能的连接点通知 Advice 需要实现的功能切面 Aspect Java语言中,将切入点和通知等组装在一起的代码单元目标对象 Target 要操作的对象织入 Weave 将功能加入到切入点中的过程1) 编写service类
public class UserServiceImpl { public void addUser(){ } }2) 编写通知 , 实现MethodBeforeAdvice接口
public class AOPTest implements MethodBeforeAdvice { //method 要执行的方法 // args 方法的参数 // target 方法所在的对象 public void before(Method method, Object[] args, Object target) throws Throwable { } }3)配置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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--目标对象--> <bean id="userService" class="com.woniuxy.spring.aop.service.impl.UserServiceImpl"/> <!--通知: 实现了打日志的功能--> <bean id="beforeExecution" class="com.woniuxy.spring.aop.component.BeforeExecution"/> <!--切入点:选出了需要增加功能的方法--> <bean id="pointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <!--value的路径必须要精确到方法--> <property name="pattern"value="com.woniuxy.spring.aop.service.impl.UserServiceImpl.addUser"/> </bean> <!--切面:连接切入点和通知,让打日志功能在切入点的位置执行--> <bean id="aspect" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="pointCut"/> <property name="advice" ref="beforeExecution"/> </bean> <!--包装userService--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> </beans>