在Spring的历史中,我们曾经使用XML文件进行各种文件的装载与注入,但是由于XML需要额外的文件去维护,导致了代码的可读性较低、程序员编写代码较慢的问题。注解的诞生解决了很多问题。
注解的作用
- 不是程序本身,但是可以对程序做出解释。
- 可以被其他程序(比如:编译器等)读取。(必须被解析器解析,如果不解析,没有作用的)
- 编写文档:通过代码里面标识的注解生成文档【生成文档doc文档】
- 代码分析:通过代码里标识的注解对代码进行分析【使用反射】
- 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查
注解使用场景
可以附加在 package,class,method,field 等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元素的访问。
元注解
元注解,就是定义注解的注解,也就是说这些元注解是的作用就是专门用来约束其它注解的注解。请区别上面那三个注解,他们也是通过元注解定义而来的。
元注解有哪些呢,主要有四个@Target,@Retention,@Documented,@Inherited
元注解有:@Target,@Retention,@Documented,@Inherited
@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Documented 将此注解包含在 javadoc 中
@Inherited 允许子类继承父类中的注解
常见注解
- @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 此注解作用于一个类上,表明此类作为一个组件类,Spring需要为此类别创建一个bean.
- @Repository持久层组件,用于标注数据访问组件,即DAO组件
- @Service服务层组件,用于标注业务层组件,表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,如果需要自己改名字则:@Service(“你自己改的bean名”)。
- @Controller用于标注控制层组件(如struts中的action)
@Component、@Repository、@Service、@Controller位置以及作用?
如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
在接口前面标上@Autowired和@Qualifier注解使得接口可以被容器注入,当接口存在两个实现类的时候必须指定其中一个来注入,使用实现类首字母小写的字符串来注入,如:
@Autowired
@Qualifier(“chinese”)
private Man man;
或则可以省略,只写@Autowired.
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Bean
这是一个方法级注解,但功能却是和类注解相同的,甚至更加的强大:告诉Spring去创建一个bean供整个项目使用。通常,@Bean与@Configuration成对出现,类被@Configuration所声明表明当前类为一个配置类,Spring需要扫描去这个类,@Bean在配置类的里面修饰方法,返回一些类的实体对象作为bean供项目中其他地方使用。
bean使用
Resource注解
@Resource用法与@Autowired 用法 用法相似,也是做依赖注入的,从容器中自动获取bean。但还是有一定的区别。
@Autowired
@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。
@Resource
- @Resource默认按byName自动注入。
- 既不指定name属性,也不指定type属性,则自动按byName方式进行查找。如果没有找到符合的bean,则回退为一个原始类型进行进行查找,如果找到就注入。
- 只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。
- 只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。
spring security中可以通过表达式控制方法权限:
- @PreAuthorize
- @PostAuthorize
- @PreFilter
- @PostFilter
其中前两者可以用来在方法调用前或者调用后进行权限检查,后两者可以用来对集合类型的参数或者返回值进行过滤。
使用@PreAuthorize和@PostAuthorize进行访问控制 @PreAuthorize可以用来控制一个方法是否能够被调用
Controller层
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{
...
...
...
}
对应的service层
@Service("ss")
public class PermissionService
{
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission)
{
}
}
@PreAuthorize("@ss.hasPermi(‘system:user:query’)")表示:
- @ss标签对应的PermissionService
- hasPermi方法
- 传入参数为system:user:query,表示用户的查询权限