相比 Spring Boot 以及 Spring MVC , Spring组件使用比较多
Spring是一种开源轻量级的框架,解决JavaEE的解决方案。
“一站式”
spring--->IOC-DI依赖注入
Dog dog = new Dog();
application.xml---->声明 <bean id="dog" class="com.cng.Dog">
strcut ---> 重
spring使用注解代替xml ---> 轻量级
支持模块调用,坚持不重新造轮子。
- Spring Core
- Spring context
- Spring Web
- Spring MVC
- Spring DAO 简化JDBC编码
- Spring ORM ORM框架
- Spring AOP 面向切面编程 切片
class Test{} bean---> 实例化
AOP
@Watch("")
public void watchMovie(){
}
@Result("")
public
对事务拦截,对方法保护,增强。 事务完整性
spring资源包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.enjoy</groupId> <artifactId>spring-anno</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3.RELEASE</version> </dependency> </dependencies> </project>
XML 与 Bean 操作
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 http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="person" class="com.enjoy.cap1.Person"> <property name="name" value="james"></property> <property name="age" value="19"></property> </bean> </beans>
package com.enjoy.cap1; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainTest1 { public static void main(String args[]){ /* 把beans.xml的类 加载到容器中 */ // 读beans.xml ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml"); // 初始化 IOC容器:MAP // 从容器中获取bean Person person = (Person) app.getBean("person"); System.out.println(person); } }
Bean开发
package com.enjoy.cap1.config; import com.enjoy.cap1.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //配置文件 spring 注解的方式将bean加载到容器当中去 @Configuration public class MainConfig { // 获取person的方法 @Bean public Person person(){ return new Person("jamees", 20); } // 这个方式和刚才写xml的效果是一样的,但是这个当时更加简洁 }
1 package com.enjoy.cap1; 2 3 import com.enjoy.cap1.config.MainConfig; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 6 7 public class MainTest2 { 8 public static void main(String args[]){ 9 10 ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class); 11 /** AnnotationConfigApplicationContext 容器类 **/ 12 13 // 容器中获取bean 14 Person person = (Person) app.getBean("person01"); 15 16 System.out.println(person); 17 18 String[] nameForBean = app.getBeanNamesForType(Person.class); 19 for(String name:nameForBean){ 20 System.out.println(name); 21 } 22 23 } 24 }
@Configuration 配置类
@ComponentScan扫描规则
- 1.指定扫描范围
- 2.扫描过滤器
- 3.自定义过滤规则
<scope>test</scope> 作用域
1 import com.enjoy.cap2.config.Cap2MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap2Test { 6 7 @Test 8 public void test01(){ 9 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap2MainConfig.class); 10 // 相关东西加载到容器中 11 12 String[] names = app.getBeanDefinitionNames(); 13 14 for(String name:names){ 15 System.out.println(name); 16 } 17 }
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap2MainConfig
orderConteroller
orderDao
orderService
person01
1 package com.enjoy.cap2.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.ComponentScan; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.FilterType; 9 import org.springframework.stereotype.Controller; 10 11 @Configuration 12 @ComponentScan(value="com.enjoy.cap2", includeFilters = { 13 14 @ComponentScan.Filter(type= FilterType.ANNOTATION, classes={Controller.class}) 15 16 }, useDefaultFilters = false) // 扫描组建 17 18 /** 19 * value 包的地址 20 * includeFilters 声明组件的作用范围 21 * useDefaultFilters 不按照默认的情况 22 * */ 23 24 public class Cap2MainConfig { 25 @Bean 26 public Person person01(){ 27 return new Person("jamees", 20); 28 } 29 }
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
cap2MainConfig
orderConteroller
person01
1 package com.enjoy.cap2.config; 2 3 4 import com.enjoy.cap1.Person; 5 import com.enjoy.cap2.controller.OrderConteroller; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.ComponentScan; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.context.annotation.FilterType; 10 11 12 @Configuration 13 @ComponentScan(value="com.enjoy.cap2", includeFilters = { 14 15 @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, classes={OrderConteroller.class}) 16 17 }, useDefaultFilters = false) // 扫描组建 18 19 /** 20 * value 包的地址 21 * includeFilters 声明组件的作用范围 ANNOTATION 注解类型 22 * useDefaultFilters 不按照默认的情况 ture 加载默认配置 23 * */ 24 25 public class Cap2MainConfig { 26 @Bean 27 public Person person01(){ 28 return new Person("jamees", 20); 29 } 30 }
将自定义的信息,加入到扫描里面
方便配置和业务相关的信息,而不是将所有的信息都录入、加载配置。
1 package com.enjoy.cap2.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.ComponentScan; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.FilterType; 9 10 11 @Configuration 12 @ComponentScan(value="com.enjoy.cap2", includeFilters = { 13 14 @ComponentScan.Filter(type= FilterType.CUSTOM, classes={JamesTypeFilter.class}) 15 16 }, useDefaultFilters = false) // 扫描组建 17 18 /** 19 * value 包的地址 20 * includeFilters 声明组件的作用范围 ANNOTATION 注解类型 21 * useDefaultFilters 不按照默认的情况 ture 加载默认配置 22 * */ 23 24 public class Cap2MainConfig { 25 @Bean 26 public Person person01(){ 27 return new Person("jamees", 20); 28 } 29 }
1 /*** 2 * 自定义的信息 3 */ 4 5 package com.enjoy.cap2.config; 6 7 import org.springframework.core.io.Resource; 8 import org.springframework.core.type.AnnotationMetadata; 9 import org.springframework.core.type.ClassMetadata; 10 import org.springframework.core.type.classreading.MetadataReader; 11 import org.springframework.core.type.classreading.MetadataReaderFactory; 12 import org.springframework.core.type.filter.TypeFilter; 13 14 import java.io.IOException; 15 16 public class JamesTypeFilter implements TypeFilter { 17 private ClassMetadata classMetadata; 18 19 20 /** 21 * MetadataReader : 拿到元数据 读取到当前正在扫描类的信息 22 * MetadataReaderFactory : 可以获取到其他任何类的信息 23 */ 24 25 public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { 26 // 虎丘当前注解的信息 27 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); 28 // 获取当前正在扫描的类信息 29 classMetadata = metadataReader.getClassMetadata(); 30 // 获取当前资源(类的路径) 31 Resource resource = metadataReader.getResource(); 32 33 String className = classMetadata.getClassName(); 34 System.out.println("---->"+className); 35 36 // 自定义注解 信息 Config默认加载进来 37 if(className.contains("er")){ // 当类包含er字符,则匹配成功,返回true 38 return true; 39 } 40 41 return false; 42 } 43 }
1 import com.enjoy.cap2.config.Cap2MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap2Test { 6 7 @Test 8 public void test01(){ 9 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap2MainConfig.class); 10 // 相关东西加载到容器中 11 12 String[] names = app.getBeanDefinitionNames(); 13 14 for(String name:names){ 15 System.out.println(name); 16 } 17 } 18 }
结果:
1 ---->com.enjoy.cap2.config.JamesTypeFilter 2 ---->com.enjoy.cap2.controller.OrderConteroller 3 ---->com.enjoy.cap2.dao.OrderDao 4 ---->com.enjoy.cap2.service.OrderService 5 org.springframework.context.annotation.internalConfigurationAnnotationProcessor 6 org.springframework.context.annotation.internalAutowiredAnnotationProcessor 7 org.springframework.context.event.internalEventListenerProcessor 8 org.springframework.context.event.internalEventListenerFactory 9 cap2MainConfig 10 jamesTypeFilter 11 orderConteroller 12 orderDao 13 orderService 14 person01
其中
@ComponentScan(value="com.enjoy.cap2", includeFilters = {
@ComponentScan.Filter(type= FilterType.CUSTOM, classes={JamesTypeFilter.class})
}, useDefaultFilters = false) // 扫描组建
可以多次叠加
@Scope 扫描规则
spring默认是单实例还是多实例的
在使用的时候才会创建bean
IOC容器:
- 多实例:仅当bean被使用的时候才创建
- 单实例:创阿金IOC容器的时候实例bean就被创建
1 import com.enjoy.cap3.config.Cap3MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap3Test { 6 7 @Test 8 public void test01(){ 9 // 创建容器将bean加载进来 10 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap3MainConfig.class); 11 // 相关东西加载到容器中 12 13 String[] names = app.getBeanDefinitionNames(); 14 15 for(String name:names){ 16 System.out.println(name); 17 } 18 19 // 从容器中分别取两次person实例,看是否为同一个bean 20 Object bean1 = app.getBean("person"); 21 Object bean2 = app.getBean("person"); 22 23 System.out.println(bean1 == bean2); 24 // 结论:bean1就是bean2,是同一个对象 25 } 26 }
1 package com.enjoy.cap3.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Scope; 8 9 10 @Configuration 11 public class Cap3MainConfig { 12 /*** 13 * prototypr:多实例 IOC容器启动的时候,IOC容器启动并不会调用方法创建对象,而是每次获取的时候才会调用方法创建爱你对象 14 * singleton:单实例(默认):IOC容器启动的时候回调用方法创建对象并放到IOC容器中,以后灭磁回去的是就是直接从容器中拿(大Map.get)到同一个bean 15 * request:主要针对一web应用,递交一次请求创建一个实例 16 * session:同一个session创建一个实例 17 */ 18 19 @Scope("prototype") 20 21 // 给容器中注册一个bean,类型为返回值的类型,默认是单实例 22 @Bean 23 public Person person(){ 24 return new Person("james", 20); 25 } 26 }
@lazy懒加载
1 package com.enjoy.cap4.config; 2 3 4 import com.enjoy.cap1.Person; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Lazy; 8 9 10 11 @Configuration 12 public class Cap4MainConfig { 13 /*** 14 * 懒加载:主要针对单实例bean:默认在容器启动的时候创建对象 15 * 懒加载:容器启动时候不创建对象,一个延时等待的作用,仅当第一次使用(获取)bean的时候才创建初始化 16 */ 17 18 @Lazy 19 @Bean 20 public Person person(){ 21 System.out.println("给容器中添加person...."); 22 return new Person("james", 20); 23 } 24 }
1 import com.enjoy.cap4.config.Cap4MainConfig; 2 import org.junit.Test; 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Cap4Test { 6 7 @Test 8 public void test01(){ 9 // 创建容器将bean加载进来 10 AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap4MainConfig.class); 11 // 相关东西加载到容器中 12 13 14 System.out.println("IOC容器创建完成........"); 15 Object bean1 = app.getBean("person"); // 执行获取的时候才创建并初始化bean 16 System.out.println(bean1); 17 } 18 }
很大容器就是个大map.get()