Java框架--注解模式:@Repository @Service @Controller @Autowired

Java面向对象本质:

找到类--创建对象--给属性赋值--调用方法
xml--bean(找到类)--beanFactory(创建对象-反射)--property(set注入、构造注入、工厂注入)--getBean(从beanFactory)获取对象--对象调用方法
注解模式--context扫包--给类加@Component注解(找到类)--beanFactory(创建对象-反射)--@Autowired--getBean(从beanFactory)获取对象--对象调用方法

注解配置步骤:

1、扫包    
2、加注解@Component组件注解--其他地方都是用@Component
   在spring3.x以后延伸了3个和@Component等效的注解
   @Repository  用于DAO实现类的注解--单例模式@Scope("singleton")
   @Service     用于Servers实现类的注解--单例模式@Scope("singleton")
   @Controller  用于Controller实现类的注解,spring将@Controller设置为--多例模式@Scope("prototype")
3、key由来:
	第一种:将注解类的类名第一个字母小写   UserController==userController
	第二种:注解中标注别名 @Controller("usercon")
4、@Autowired默认注入方式是根据类型(类)去注入,而不是根据id

代码测试:

DAO层定义一个interface
package com.ioc.dao;

public interface IUserDao {

	public void addUser();
}

定义一个实现类
package com.ioc.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao implements IUserDao{

	@Override
	public void addUser() {
		System.out.println("调用了UserDao的addUser方法!");
	}
}


Service层
package com.ioc.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ioc.dao.IUserDao;

@Service
//@Component  等同于  @Service
public class UserService {

	@Autowired
	private IUserDao userDao;
	
	public void addUser() {
		userDao.addUser();
	}
}


Controller层
package com.ioc.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.ioc.service.UserService;

@Controller
public class UserController {

	@Autowired(required=false)//required=false  依赖的UserDao  bean没注册,也不报错
	private UserService userServer;
	
	public void addUser(){
		userServer.addUser();
	}
}


测试类:
package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ioc.web.UserController;

public class Test3 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		UserController userController = (UserController) context.getBean("userController");
		userController.addUser();
	}
}


运行结果:
十二月 15, 2016 3:39:23 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@579bb367: startup date [Thu Dec 15 15:39:23 CST 2016]; root of context hierarchy
十二月 15, 2016 3:39:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
调用了UserDao的addUser方法!


注解:@Resource、@Autowired、@Qualifier

定义第二个接口的实现类
package com.ioc.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao2 implements IUserDao {

	@Override
	public void addUser() {
		System.out.println("调用了UserDao的addUser222222方法!");
		
	}

}


修改service层
public class UserService {

	@Autowired
	private IUserDao xxx;
	
	public void addUser() {
		xxx.addUser();
	}
}

会报错:
Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ioc.dao.IUserDao com.ioc.service.UserService.xxx; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.ioc.dao.IUserDao] is defined: expected single matching bean but found 2: userDao,userDao2
	
如果此时想调用UserDao2,并且写法private IUserDao xxx;
需要修改service层
public class UserService {

	@Autowired
	@Qualifier("userDao2")  //
	private IUserDao xxx;
	
	public void addUser() {
		xxx.addUser();
	}
}


@Resource(name="userDao2")等同于
@Autowired
@Qualifier("userDao2")


注意:@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常 而@Resource默认按byName自动注入罢了。其实spring注解,最常用的还是根据名称,根据类型啊,构造方法啊,用的非常少。所以在多个实现的时候我们定义好bean的名称就行,就不会错乱。



你可能感兴趣的:(Java框架)