1.spring依赖注入的原理
链接:https://www.cnblogs.com/mthoutai/p/7278427.html
假设我们去看Spring的源代码可能涉及的类和接口相当多,不易掌握。在此我用自己的代码和方式来帮助我们Spring依赖注入的过程。
当我们启动Spring容器的时候他会运行以下几个过程:
(1、载入Xml配置文件(readXML(String filename))在Spring这个由ApplicationContext类完毕
这一步会解析Xml属性。把bean的属性存放到BeanDefinition类中
代码例如以下:
1 /** 2 * 读取xml配置文件 3 * @param filename 4 */ 5 private void readXML(String filename) { 6 SAXReader saxReader = new SAXReader(); 7 Document document=null; 8 try{ 9 URL xmlpath = this.getClass().getClassLoader().getResource(filename); 10 document = saxReader.read(xmlpath); 11 Map<String,String> nsMap = new HashMap<String,String>(); 12 nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间 13 XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径 14 xsub.setNamespaceURIs(nsMap);//设置命名空间 15 List<Element> beans = xsub.selectNodes(document);//获取文档下全部bean节点 16 for(Element element: beans){ 17 String id = element.attributeValue("id");//获取id属性值 18 String clazz = element.attributeValue("class"); //获取class属性值 19 BeanDefinition beanDefine = new BeanDefinition(id, clazz); 20 XPath propertysub = element.createXPath("ns:property"); 21 propertysub.setNamespaceURIs(nsMap);//设置命名空间 22 List<Element> propertys = propertysub.selectNodes(element); 23 for(Element property : propertys){ 24 String propertyName = property.attributeValue("name"); 25 String propertyref = property.attributeValue("ref"); 26 PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref); 27 beanDefine.getPropertys().add(propertyDefinition); 28 } 29 beanDefines.add(beanDefine); 30 } 31 }catch(Exception e){ 32 e.printStackTrace(); 33 } 34 }
(2、Bean的实例化
在配置文件以bean的id为key。BeanDefinition为value放到Map中
1 /** 2 * 完毕bean的实例化 3 */ 4 private void instanceBeans() { 5 for(BeanDefinition beanDefinition : beanDefines){ 6 try { 7 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) 8 sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance()); 9 } catch (Exception e) { 10 e.printStackTrace(); 11 } 12 } 13 14 }
(3、为Bean的输入注入值。完毕依赖注入
1 /** 2 * 为bean对象的属性注入值 3 */ 4 private void injectObject() { 5 for(BeanDefinition beanDefinition : beanDefines){ 6 Object bean = sigletons.get(beanDefinition.getId()); 7 if(bean!=null){ 8 try { 9 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); 10 for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){ 11 for(PropertyDescriptor properdesc : ps){ 12 if(propertyDefinition.getName().equals(properdesc.getName())){ 13 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private 14 if(setter!=null){ 15 Object value = sigletons.get(propertyDefinition.getRef()); 16 setter.setAccessible(true); 17 setter.invoke(bean, value);//把引用对象注入到属性 18 } 19 break; 20 } 21 } 22 } 23 } catch (Exception e) { 24 } 25 } 26 } 27 }
事实上Spring依赖注入的过程就是这么简单,再就是各种细节了。比方懒载入、单例等的额外处理了。
2.linux脚本
之前写过bash shell脚本 。略。
3.集群搭建
一般都是下载相关的包,解压,部署依赖环境,配置环境变量。略
4.常用spring注解
@Component
作用: 用于把当前类对象存入spring容器中
属性: value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写
1 @Component 2 public class AccountDaoImpl implements IAccountDao { 3 public void saveAccount() { 4 System.out.println("保存了账户1111111111111"); 5 } 6 }
在bean.xml中配置
<context:component-scan base-package="com.itheima"></context:component-scan>
测试代码
1 public static void main(String[] args) { 2 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); 3 IAccountDao dao = ac.getBean("accountDaoImpl",IAccountDao.class); 4 System.out.println(dao); 5 dao.saveAccount(); 6 ac.close(); 7 }
由Component衍生而来的注解:
Controller:一般用在表现层
Service: 一般用在业务层
Repository:一般用在持久层
@Autowired
按照类型注入,有多个接口的实现会报错
自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错;
如果Ioc容器中有多个类型匹配时:先按照类型匹配,如果找到多个类型bean对象,再按照变量名作为bean的id去匹配,如果id不匹配,报错
Autowired出现位置: 可以是变量上,也可以是方法上
细节:在使用注解注入时,set方法就不是必须的了。
@Qualifier
用于注入数据的注解
但是在给方法参数注入时可以的
属性:value:用于指定注入bean的id
@Resource
作用:直接按照bean的id注入。它可以独立使用
属性:name:用于指定bean的id
注意: @Resource`是由JDK提供的注解,在JDK1.9之后移除到扩展模块之中.
所以如果想使用`@Resource`注解注入数据,请使用1.8及以下版本JDK
@Value
作用:用于注入基本类型和String类型的数据
属性:value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)SpEL的写法:${表达式}
@Scope
指定bean的作用范围。
属性:
value:指定范围的值。 取值:`singleton` `prototype` `request` `session` `globalsession`
5.数据库创建索引
6.创建视图