1.spring常用注解。
1> @component 注解
@controller 控制器
@service 服务
@repository dao
@component 泛指组件(把普通pojo实例化到spring容器中,相当于配置文件中的
@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。
下面写这个是引入component的扫描组件
2>@Autowired与@Resource
两者都可以用来装配bean,可以写在字段上,也可以写在setter方法上
@Autowired:默认是按类型来装配的,
如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) private String phoneNumber;
如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:@Autowired() @Qualifier(“phoneNumber”) private String phoneNumber;
@Resource:默认是按名称来报销的,名称可以通过name属性来指定 如下:
@Resource (name=“number”)
private String phoneNumber;
3>.@Configuration:用在类上,声明此类为配置类。
4> @Bean:注解在方法上,声明方法的返回值为一个bean
5> @Aspect :注解在类上,声明类为一个切面,@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
@After 在方法执行之后执行(方法上)
@Before 在方法执行之前执行(方法上)
@Around 在方法执行之前与之后执行(方法上)
@PointCut 声明切点 在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)
6>.@Value:为属性注入值(属性上)支持如下方式的注入:
》注入普通字符 :@Value("Michael Jackson")String name;
》注入操作系统属性 :@Value("#{systemProperties['os.name']}")String osName;
》注入表达式结果 :@Value("#{ T(java.lang.Math).random() * 100 }") String randomNumber;
》注入其它bean属性 :@Value("#{domeClass.name}")String name;
》注入文件资源 :@Value("classpath:com/hgs/hello/test.txt")String Resource file;
》注入网站资源 :@Value("http://www.cznovel.com")Resource url;
》注入配置文件 :Value("${book.name}")String bookName;
7>.异步相关
@EnableAsync 配置类中,此注解开启对异步任务的支持,叙事性AsyncConfigurer接口(类上)
@Async 在实际执行的bean方法使用该注解来申明其是一个异步任务(方法上或类上所有的方法都将异步,需要@EnableAsync开启异步任务)
8>.定时任务相关
@EnableScheduling 在配置类上使用,开启计划任务的支持(类上)
@Scheduled 来申明这是一个任务,包括cron,fixDelay,fixRate等类型(方法上,需先开启计划任务的支持)
9>.@Enable*
@EnableTransactionManagement 开启注解式事务的支持
@EnableCaching 开启注解式的缓存支持
10>.测试相关注解
@RunWith 运行器,Spring中通常用于对JUnit的支持
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration 用来加载配置ApplicationContext,其中classes属性用来加载配置类
@ContextConfiguration(classes={TestConfig.class})
11>.其他注解
@RequestMapping 用于映射Web请求,包括访问路径和参数(类或方法上)
@ResponseBody 支持将返回值放在response内,而不是一个页面,通常用户返回json数据(返回值旁或方法上)
@RequestBody 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,
@ExceptionHandler 用于全局处理控制器里的异常
2.Spring依赖注入(Dependency Injection)和控制反转(Inversion of Control)
什么是依赖注入:
具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的 工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
依赖注入的应用场景:
1>.类很多的时候,更改代码会引发编译很多依赖这个类的类,对庞大的系统构建而言,很慢;
2>.需求变化大
3.SpringAOP
什么是AOP(Aspect-Oriented Programming,面向切面编程):
Java是一个面向对象(OOP)的语言,但它有一些弊端,当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志,权限验证,事务等功能 时,只能在在每个对象里引用公共行为,这样做不便于维护,而且有大量重复代码。AOP的出现弥补了OOP的这点不足。
实现AOP的方法:
方法一:静态代理
//接口
public interface IUserDao{
void add();
}
//目标对象
public class UserDao implements IUserDao{
public void add(){
System.out.println("add a book");
}
}
//代理对象(静态代理)
public class UserDaoProxy implements IUserDao{
private IUserDao target;
public UserDaoproxy(IUserDao target ){
this.target=target;
}
public void save(){
System.out.println("开始事物。。。。");
target.add();//执行目标对象的方法
System.out.println("提交事务。。。");
}
}
// 测试类
public class Test{
public static void main(String [] args){
//目标对象
UserDao target=new UserDao();
//代理对象
UserDAoProxy proxy=newUserDaoProxy(target);
proxy.add();//执行代理方法
}
}
静态代理的特点:
(优点)1>.符合开闭原则,在不修改目标对象的前提下,对目标对象进行功能扩展。
(缺点 1>.因为代理类和目标对象一样实现接口,所以会有很多代理类,代理类终会有很多方法,几乎相同
2>. 一旦接口增加方法,目标类和代理类都要维护(实现接口中的方法)
方法二:动态代理:
(JDK动态代理)
实现invocationHanlder接口,重写invoke方法
解决静态代理必须要实现接口中所有的方法,
需要业务类(被代理类实现接口)
//接口
public interface IUserDao{
void add();
}
//目标对象
public class UserDao implements IUserDao{
public void add(){
System.out.println("add a book");
}
}
//代理对象(动态代理)
public class PerformanceHandler implements InvocationHandler {
private Object target;
public PerformanceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {
System.out.println("开始事物。。。。");
Object obj = arg1.invoke(target, arg2);// 通过反射机制调用目标对象的方法
System.out.println("提交事务。。。");
return obj;
}
}
// 测试类
public class Test{
public static void main(String[] args) {
IUserDao iUserDao= new UserDao();
// 将目标业务类和横切代码编织到一起
PerformanceHandler handler = new PerformanceHandler(iUserDao);
// 根据编织了目标业务类逻辑和性能监视横切逻辑的InvocationHandler实例创建代理实例
IUserDao proxy = (IUserDao) Proxy.newProxyInstance(iUserDao
.getClass().getClassLoader(), iUserDao.getClass()
.getInterfaces(), handler);
proxy.add();
}
}
CGLIB动态代理:
定义业务类,业务类无需实现接口(也可以实现)
实现MethodInterceptor接口; ,创建代理类。
创建增强器。Enhancer enhancer=new Enhacer();
为增强类指定要代理的业务类,为代理类指定父类
enhancer.setSuperclass(this.target.getClass);
对于代理类的所有方法的调用,都会调用callback,需要Intercept方法进行拦截
enhancer.setCallback(this);
重写intercept方法。
特点:只需要指定业务类,不需要业务类实现接口。
对final修饰的类无法代理