文章目录
- 1. Spring 之旅 (Spring简介以及基础知识)
- 1. Spring 上下文(XML)
- 2. Spring容器
- 2. 装配Bean
- 1. 装配机制
- 2.自动化装配Bean
- 3. 环境与profile
- 1. javaConfig和XML,profile配置
- 2. 条件化Bean
- 3. 自动装配歧义性
- 4. bean的作用域
- 5. 运行时值注入(properties & spel)
- 4. 面向切面的Spring
- 1. 什么是面向切面编程
- 2. 通过切点选择连接点
- 3. 使用注解创建切面
- 5. 构建Spring Web应用程序
- 1. Spring mvc起步
- 2. 使用flash属性
- 6. Spring security
- 1. 简介
1. Spring 之旅 (Spring简介以及基础知识)
1. Spring 上下文(XML)
- 通过XML进行Bean配置的时候,可以通过ClassPathXmlApplicationContext加载spring的上下文。通过上下文可以获取Bean。
2. Spring容器
- Bean工厂:BeanFactory,提供基础的DI支持。
- ApplicationContext:基于BeanFactory构建,并提供应用框架级别的服务。
- FileSystemXmlApplication: 从文件系统下的加载一个或多个XML文件。
- ClassPathXmlApplicationContext: 从类路径下加载。
- AnnotationConfigApplicationContext: 从配置类中加载。
2. 装配Bean
1. 装配机制
- 在XML中显示配置。
- 在java中进行显示配置。
- 隐式的Bean发现机制和自动装配。
2.自动化装配Bean
- 提供了两个角度去实现自动化装配:
- 组件扫描:Spring 会自动发现应用上下文中所有创建的Bean。
- 自动扫描:Spring自动满足Bean之间的依赖。
- @Named = @Component
- 对于强依赖性使用构造函数注入,弱依赖性则使用setter注入。
- 使用XML装配
- constructor == c-命名空间
- properties == p-命名空间
- javaConfig和XML互相装配形式:
- 组合装配Bean,使用@Import(XXConfig.class),把别的config中的Bean,带入到这个config中使用。
- 组合装配XML中的Bean,使用
@ImportResource("classpath:cd-config.xml")
; - 需要把javaConfig装配的Bean,加载到XMl中,使用
<bean class="XXXConfig"/>
。 - 需要把XML装配到另外的XML中,使用
<import resoune="XXConfig.xml">
3. 环境与profile
1. javaConfig和XML,profile配置
- javaConfig, 使用@Profile进行环境配置,在Spring3.1只能使用在类上,Spring3.2之后能够使用在方法上。
- XML中进行环境配置,在
<beans profile="dev"/>
。
2. 条件化Bean
- 定义:
- 希望一个或多个bean只有在应用的类包路径下包含特定的库时才会创建。
- 希望某个bean只有当另外某个特定的bean也声明之后才会创建。
- 要求只有某个特定环境变量设置之后,才会创建某个bean。
- 实现:
- spring 4引入了@Conditional,只有当条件为真的时候,才会创建bean。
- 设置给@Conditional的类,必须实现Condition接口,重写matches方法。
- 详解代码
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
public interface ConditionContext {
BeanDefinitionRegistry getRegistry(); // 获取注册的bean
// conditionContext.getRegistry().containsBeanDefinition("person") 是否已经注册了person bean
ConfigurableListableBeanFactory getBeanFactory(); // 获取提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题).
Environment getEnvironment(); // 获取环境配置
ResourceLoader getResourceLoader(); // ResourceLoader所加载的资源
ClassLoader getClassLoader(); // 获取类加载器
}
public interface AnnotatedTypeMetadata { // 被加上注解的源数据信息。
boolean isAnnotated(String var1);
Map<String, Object> getAnnotationAttributes(String var1);
Map<String, Object> getAnnotationAttributes(String var1, boolean var2);
MultiValueMap<String, Object> getAllAnnotationAttributes(String var1);
MultiValueMap<String, Object> getAllAnnotationAttributes(String var1, boolean var2);
}
3. 自动装配歧义性
- 重现歧义:
- 存在多个实现类实现了同一个接口,并且这多个实现类都注入到了Spring容器内。
- 使用@Autowired注入接口,因为需要面向接口编程。
- Spring便会报错,无法识别,需要注入的是哪一个实现类的bean。
- 解决方法:
- 只有我们使用@primary去定义三个实现类谁是最优先注入的。
- 直接写明(@qualifier(“className”))需要注入的是哪个实现类, 在实现类上使用@Component + @Qualifier(“className”)。
- 歧义: 出现同样的@Qualifier,一样会导致Spring报错。
- 解决方法:
- 增加多个@Qualifier, 但是java会报错,不允许在同一个类上增加多个同样的注解。
- 自己封装@Qualifier,定义不同名称的@Qualifier注解。
@Target({ElementType.FIELD, ElementType.METHOD,
ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface ColdQualifier {
}
4. bean的作用域
- 作用域:
- 单例(Singleton): 整个应用中,只创建一个bean实例。
- 原型(Prototype): 在每次注入或是通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
- 会话(Session): 在web应用中,为每个会话创建一个bean实例。
- 请求(Request):在web应用中,为每个请求创建一个bean实例。
- 实现: @Scope(“prototype”), 默认是单例的。
5. 运行时值注入(properties & spel)
- 注入外部的值
- 使用@PropertySource(“classapth: XXX.properties”)。
- 使用 Environment 注入值
- 使用@autowried Environment env。
- 使用env.getProperty(“key”)。
- 使用解析属性占位符
- @Value("${key}") String key;
// 使用占位符去获取properties文件中的数据,必须要配置解析器。
@Bean
public PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
// ***: classpath:XX.propertise; classpath之后不能存在空格,否则无法找到文件.
@Component
@PropertySource("classpath:properties/customer.properties")
public class PropertiesDemo {
@Value("${alex.name}")
private String alexName;
public void sayName(){
System.out.println(this.alexName);
}
}
- SPEL表达式
- 表示字面值:#{3.1415}
- 引用bean、属性、方法:#{customer}, #{customer.name},#{customer.sayName()}
- 表达式中使用类型:#{T(java.lang.Math)}, #{T(java.lang.Math).PI},#{T(java.lang.Math).random()}
- 运算符:
-
#{2 * T(java.lang.Math).PI * circle.radius}
; - ^可以表示乘方。
- 字符串连接:#{disc.tiitle + ‘by’ + disc.name}。
- 判断等于:#{disc.name == ‘alex’}; #{disc.name eq ‘alex’}。
- 正则表达式:#{admin.email matches '[a-zA-Z0-9.%±] '}。
- 集合运算:#{list[2].title}; #{‘This is txt’[3]}
4. 面向切面的Spring
1. 什么是面向切面编程
- Spring切面的5中通知类型:
- 前置通知(Before):在目标方法调用之前调用。
- 后置通知(After):在目标方法完成之后调用,此时不会关心方法的输出是什么。
- 返回通知(After-returning):在目标方法成功执行之后调用。
- 异常通知(After-throwing):在目标方法异常之后调用。
- 环绕通知(Around):在目标方法执行之前之后调用。
2. 通过切点选择连接点
- execution(* concert.performance.perform(…) && within(concert.*)):
&& == and ; || == or ! == not
- execution() and bean(‘bean ID’); 只切到存在这个bean的切面。
- execution() and !bean(‘bean ID’);不切存在这个bean的切面。
3. 使用注解创建切面
- 使用@Aspect定制切面类。
- 使用@PointCut定义切点。
- 使用其他的通知包围切点。
5. 构建Spring Web应用程序
1. Spring mvc起步
1. DispacherServlet:将请求发送给SpringMVC控制器中。
2. 使用flash属性
- 定义:为了解决重定向之后,数据不丢失问题。Spring通过RedirectAttributes来保存数据。 Spring管理了会话,不需要我们去释放会话。RedirectAttributes也是把数据放在会话中进行传递。
RedirectAttributes model = new redirectAttributes();
model.addFlashAttrobute("key", object)。
eg: "redirect:/spitter"
在spitter Controller中,使用参数Model来获取会话中数据。
6. Spring security
1. 简介
- 解决方法角度
- 使用Servlet的Filter保护web的请求并限制URL级别的访问。
- 使用Spring AOP保护方法的调用–借助对象代理和使用通知,做到确保只有具备适当权限的用户才能访问安全保护的方法。336