家裡瓷磚縫隙難清洗?用這一招,瞬間變新瓷磚,太省錢了!

2{icon} {views}

我們家裡瓷磚用久了會有很多的污漬,非常難清洗乾凈,這個問題困擾了很多家庭主婦。 
今天給大家分享清洗瓷磚的好方法,再難清理的污垢都能清理掉,清潔阿姨打掃的都沒這麼乾凈!
瓷磚清潔劑 
像白醋、酒精、洗衣服都有強大的清潔功能,教大家自製一瓶瓷磚清潔劑,只要把它們再加上麵粉,瓷磚縫隙頑固的污漬都能輕鬆去除,一起看看怎麼做吧。 
1、 找一個普通的塑料瓶,裝半瓶水。 
  

2、加入半瓶蓋的洗衣粉或者肥皂粉。 
  
3、加入一瓶蓋的麵粉,麵粉除了用來吃,它清潔油污的能力,千萬別小看它。 
  

4、加入兩瓶蓋白醋,白醋可以去味,又有強大清潔功能。 
  
5、加入三瓶蓋酒精,如果沒有酒精,白酒也是可以用。 
  

6、最後搖勻即可,用抹布沾濕抹要清潔的地方,然後用這個清潔劑擦拭,就算有紋路的大理石磚,也能輕鬆擦乾凈。 
  
7、衛生間牆壁瓷磚也可以用這個清潔劑去擦,縫隙處拿舊牙刷刷,最後用抹布擦乾凈,牆壁就煥然一新了。 



個人覺得在家自製清潔劑,天然環保還實用,減少對人體的傷害,還能把家裡的瓷磚清洗乾凈,讓你家看起來跟新的一樣。

本站聲明:網站內容來源http://www.look543.com,如有侵權,請聯繫我們,我們將及時處理

電子菸
電子煙
電子菸

spring源碼解析之IOC容器(二)——加載和註冊

3{icon} {views}

  上一篇跟蹤了IOC容器對配置文件的定位,現在我們繼續跟蹤代碼,看看IOC容器是怎麼加載和註冊配置文件中的信息的。開始之前,首先我們先來了解一下IOC容器所使用的數據結構——-BeanDefinition,它是一個上層接口,有很多實現類,分別對應不同的數據載體。我們平時開發的時候,也會定義很多pojo類,來作為獲取數據的載體。最常見的就是,從數據庫中獲取數據之後,使用一個定義的pojo來裝載,然後我們就可以在程序中使用這個pojo類來編寫各種業務邏輯。同樣,IOC容器首先會讀取配置的XML中各個節點,即各個標籤元素,然後根據不同的標籤元素,使用不同的數據結構來裝載該元素中的各種屬性的值。比如我們最熟悉的<bean>標籤,就是使用AbstractBeanDefinition這個數據結構,接下來的分析中我們可以看到。

  先回到上篇資源的定位那裡,代碼如下:

 1 public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
 2         ResourceLoader resourceLoader = getResourceLoader();
 3         if (resourceLoader == null) {
 4             throw new BeanDefinitionStoreException(
 5                     "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
 6         }
 7 
 8         if (resourceLoader instanceof ResourcePatternResolver) {
 9             // Resource pattern matching available.
10             try {
11                 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
12                 int loadCount = loadBeanDefinitions(resources);
13                 if (actualResources != null) {
14                     for (Resource resource : resources) {
15                         actualResources.add(resource);
16                     }
17                 }
18                 if (logger.isDebugEnabled()) {
19                     logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
20                 }
21                 return loadCount;
22             }
23             catch (IOException ex) {
24                 throw new BeanDefinitionStoreException(
25                         "Could not resolve bean definition resource pattern [" + location + "]", ex);
26             }
27         }
28         else {
29             // 定位到資源之後,封裝成一個resource對象
30             Resource resource = resourceLoader.getResource(location);
31             int loadCount = loadBeanDefinitions(resource);
32             if (actualResources != null) {
33                 actualResources.add(resource);
34             }
35             if (logger.isDebugEnabled()) {
36                 logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
37             }
38             return loadCount;
39         }
40     }

  進入loadBeanDefinitions(resource)方法,正式開始加載源碼的跟蹤:

1         @Override
2     public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
3         return loadBeanDefinitions(new EncodedResource(resource));
4     }    
 1 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
 2         Assert.notNull(encodedResource, "EncodedResource must not be null");
 3         if (logger.isInfoEnabled()) {
 4             logger.info("Loading XML bean definitions from " + encodedResource);
 5         }
 6 
 7         Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
 8         if (currentResources == null) {
 9             currentResources = new HashSet<EncodedResource>(4);
10             this.resourcesCurrentlyBeingLoaded.set(currentResources);
11         }
12         if (!currentResources.add(encodedResource)) {
13             throw new BeanDefinitionStoreException(
14                     "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
15         }
16         try {
17             InputStream inputStream = encodedResource.getResource().getInputStream();
18             try {
19                 InputSource inputSource = new InputSource(inputStream);
20                 if (encodedResource.getEncoding() != null) {
21                     inputSource.setEncoding(encodedResource.getEncoding());
22                 }
23                 return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
24             }
25             finally {
26                 inputStream.close();
27             }
28         }
29         catch (IOException ex) {
30             throw new BeanDefinitionStoreException(
31                     "IOException parsing XML document from " + encodedResource.getResource(), ex);
32         }
33         finally {
34             currentResources.remove(encodedResource);
35             if (currentResources.isEmpty()) {
36                 this.resourcesCurrentlyBeingLoaded.remove();
37             }
38         }
39     }

  進入doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法:

 1 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
 2             throws BeanDefinitionStoreException {
 3         try {
 4             Document doc = doLoadDocument(inputSource, resource);
 5             return registerBeanDefinitions(doc, resource);
 6         }
 7         catch (BeanDefinitionStoreException ex) {
 8             throw ex;
 9         }
10         catch (SAXParseException ex) {
11             throw new XmlBeanDefinitionStoreException(resource.getDescription(),
12                     "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
13         }
14         catch (SAXException ex) {
15             throw new XmlBeanDefinitionStoreException(resource.getDescription(),
16                     "XML document from " + resource + " is invalid", ex);
17         }
18         catch (ParserConfigurationException ex) {
19             throw new BeanDefinitionStoreException(resource.getDescription(),
20                     "Parser configuration exception parsing XML from " + resource, ex);
21         }
22         catch (IOException ex) {
23             throw new BeanDefinitionStoreException(resource.getDescription(),
24                     "IOException parsing XML document from " + resource, ex);
25         }
26         catch (Throwable ex) {
27             throw new BeanDefinitionStoreException(resource.getDescription(),
28                     "Unexpected exception parsing XML document from " + resource, ex);
29         }
30     }

  繼續進入registerBeanDefinitions(doc, resource)方法:

1 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
2         //此時documentReader已經是DefaultBeanDefinitionDocumentReader類了
3         BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
4         int countBefore = getRegistry().getBeanDefinitionCount();
5         documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
6         //返回當前註冊的beanDefinition的個數
7         return getRegistry().getBeanDefinitionCount() - countBefore;
8     }

  進入registerBeanDefinitions(doc, createReaderContext(resource))方法:

1 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
2         this.readerContext = readerContext;
3         logger.debug("Loading bean definitions");
4         Element root = doc.getDocumentElement();
5         doRegisterBeanDefinitions(root);
6     }

  進入doRegisterBeanDefinitions(root)方法:

 1 protected void doRegisterBeanDefinitions(Element root) {
 2         // Any nested <beans> elements will cause recursion in this method. In
 3         // order to propagate and preserve <beans> default-* attributes correctly,
 4         // keep track of the current (parent) delegate, which may be null. Create
 5         // the new (child) delegate with a reference to the parent for fallback purposes,
 6         // then ultimately reset this.delegate back to its original (parent) reference.
 7         // this behavior emulates a stack of delegates without actually necessitating one.
 8         BeanDefinitionParserDelegate parent = this.delegate;
 9         this.delegate = createDelegate(getReaderContext(), root, parent);
10 
11         if (this.delegate.isDefaultNamespace(root)) {
12             //profile屬性平時使用非常少,該屬性可以用於配置數據庫的切換(常用),使用時,需要在web.xml中配置context-parm
13             //<context-parm>
14             //    <parm-name>Spring.profiles.active</parm-name>
15             //    <parm-value>dev(在applicationContext.xml中配置的profile屬性的beans的profile屬性值)</parm-name>
16             //</context-parm>
17             //在applicationContext.xml中的配置
18             //<beans profile="dev">    </beans>
19             //<beans profile="produce">   </beans>
20             String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
21             if (StringUtils.hasText(profileSpec)) {
22                 String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
23                         profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
24                 if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
25                     if (logger.isInfoEnabled()) {
26                         logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
27                                 "] not matching: " + getReaderContext().getResource());
28                     }
29                     return;
30                 }
31             }
32         }
33 
34         preProcessXml(root);
35         parseBeanDefinitions(root, this.delegate);
36         postProcessXml(root);
37 
38         this.delegate = parent;
39     }

  這裏也用到了模板方法,preProcessXml(root)和postProcessXml(root)這兩個方法都是空實現,是留給客戶來實現自己的邏輯的。重點研究一下parseBeanDefinitions(root, this.delegate)方法:

 1 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
 2         if (delegate.isDefaultNamespace(root)) {
 3             NodeList nl = root.getChildNodes();
 4             for (int i = 0; i < nl.getLength(); i++) {
 5                 Node node = nl.item(i);
 6                 if (node instanceof Element) {
 7                     Element ele = (Element) node;
 8                     if (delegate.isDefaultNamespace(ele)) {
 9                         parseDefaultElement(ele, delegate);
10                     }
11                     else {
12                         delegate.parseCustomElement(ele);
13                     }
14                 }
15             }
16         }
17         else {
18             delegate.parseCustomElement(root);
19         }
20     }

  parseCustomElement(root)方法不需要怎麼研究,我們平時幾乎不會用到自定義的標籤,所以只跟蹤parseDefaultElement(ele, delegate)裏面的代碼:

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    //import標籤
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
    //alias標籤
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
   //bean標籤
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
  //beans標籤
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }

  可以看到,對於不同的標籤,spring採用不同的策略進行處理,重點跟蹤一下處理bean標籤的方法processBeanDefinition(ele, delegate):

 1 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
 2         //委託給delegate去進行各種標籤的解析,parseBeanDefinitionElement方法中包含了各種標籤元素的解析,
 3         //並將解析好的內容封裝成BeanDefinitionHolder對象
 4         BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
 5         if (bdHolder != null) {
 6             bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
 7             try {
 8                 // Register the final decorated instance.
 9                 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
10             }
11             catch (BeanDefinitionStoreException ex) {
12                 getReaderContext().error("Failed to register bean definition with name '" +
13                         bdHolder.getBeanName() + "'", ele, ex);
14             }
15             // Send registration event.
16             getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
17         }
18     }

  在這個方法中,delegate.parseBeanDefinitionElement(ele)是解析bean元素中各種屬性的方法,registerBeanDefinition(bdHolder, getReaderContext().getRegistry())是將封裝好的數據進行存儲的方法。先看一下解析的方法:

 1 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
 2         //獲取bean標籤的id屬性的值
 3         String id = ele.getAttribute(ID_ATTRIBUTE);
 4         //獲取bean標籤上name屬性的值
 5         String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
 6 
 7         List<String> aliases = new ArrayList<String>();
 8         if (StringUtils.hasLength(nameAttr)) {
 9             //將name的值進行分割,並將它們當作別名存到aliases中
10             String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
11             aliases.addAll(Arrays.asList(nameArr));
12         }
13 
14         String beanName = id;
15         //如果bean標籤的id沒有值,但是name屬性有值,則將name屬性的第一個值當作id的值,並從aliases中將第一個別名移除掉
16         if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
17             beanName = aliases.remove(0);
18             if (logger.isDebugEnabled()) {
19                 logger.debug("No XML 'id' specified - using '" + beanName +
20                         "' as bean name and " + aliases + " as aliases");
21             }
22         }
23 
24         if (containingBean == null) {
25             //檢查bean的唯一性
26             checkNameUniqueness(beanName, aliases, ele);
27         }
28 
29         //這裏已經是將XML中bean元素中的所有屬性都封裝到beanDefinition對象中了
30         AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
31         if (beanDefinition != null) {
32             if (!StringUtils.hasText(beanName)) {
33                 try {
34                     if (containingBean != null) {
35                         beanName = BeanDefinitionReaderUtils.generateBeanName(
36                                 beanDefinition, this.readerContext.getRegistry(), true);
37                     }
38                     else {
39                         beanName = this.readerContext.generateBeanName(beanDefinition);
40                         // Register an alias for the plain bean class name, if still possible,
41                         // if the generator returned the class name plus a suffix.
42                         // This is expected for Spring 1.2/2.0 backwards compatibility.
43                         String beanClassName = beanDefinition.getBeanClassName();
44                         if (beanClassName != null &&
45                                 beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
46                                 !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
47                             aliases.add(beanClassName);
48                         }
49                     }
50                     if (logger.isDebugEnabled()) {
51                         logger.debug("Neither XML 'id' nor 'name' specified - " +
52                                 "using generated bean name [" + beanName + "]");
53                     }
54                 }
55                 catch (Exception ex) {
56                     error(ex.getMessage(), ele);
57                     return null;
58                 }
59             }
60             String[] aliasesArray = StringUtils.toStringArray(aliases);
61             //最後將封裝好的beanDefinition、它的id、以及它的別名一起封裝成BeanDefinitionHolder對象返回
62             return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
63         }
64 
65         return null;
66     }

  我們可以得到如下信息:

  1、獲取bean標籤的id屬性和name屬性的值;

  2、name屬性是可以都有多個值的,以逗號或者分號分割;

  3、如果id沒有賦值,則取name的第一個值作為id的值。所以,我們一般都會給id賦值,這樣效率高一些;

  4、檢查以這個id標識的bean是不是唯一的;

  5、進行其他屬性的解析,並最終封裝測AbstractBeanDefinition對象,也就是我們前文中提到的數據結構;

  6、最後封裝成BeanDefinitionHolder對象之後返回。

  進入parseBeanDefinitionElement(ele, beanName, containingBean)方法,看一下其他元素的解析過程:

 1 public AbstractBeanDefinition parseBeanDefinitionElement(
 2             Element ele, String beanName, BeanDefinition containingBean) {
 3 
 4         this.parseState.push(new BeanEntry(beanName));
 5 
 6         String className = null;
 7         if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
 8             className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
 9         }
10 
11         try {
12             String parent = null;
13             if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
14                 parent = ele.getAttribute(PARENT_ATTRIBUTE);
15             }
16             AbstractBeanDefinition bd = createBeanDefinition(className, parent);
17 
18             parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
19             bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
20 
21             parseMetaElements(ele, bd);
22             parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
23             parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
24 
25             parseConstructorArgElements(ele, bd);
26             parsePropertyElements(ele, bd);
27             parseQualifierElements(ele, bd);
28 
29             bd.setResource(this.readerContext.getResource());
30             bd.setSource(extractSource(ele));
31 
32             return bd;
33         }
34         catch (ClassNotFoundException ex) {
35             error("Bean class [" + className + "] not found", ele, ex);
36         }
37         catch (NoClassDefFoundError err) {
38             error("Class that bean class [" + className + "] depends on not found", ele, err);
39         }
40         catch (Throwable ex) {
41             error("Unexpected failure during bean definition parsing", ele, ex);
42         }
43         finally {
44             this.parseState.pop();
45         }
46 
47         return null;
48     }

  解析封裝成BeanDefinitionHolder對象之後,就可以進行註冊了,先回到之前的processBeanDefinition(ele, delegate):

 1 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
 2         //委託給delegate去進行各種標籤的解析,parseBeanDefinitionElement方法中包含了各種標籤元素的解析,
 3         //並將解析好的內容封裝成BeanDefinitionHolder對象
 4         BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
 5         if (bdHolder != null) {
 6             bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
 7             try {
 8                 // Register the final decorated instance.
 9                 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
10             }
11             catch (BeanDefinitionStoreException ex) {
12                 getReaderContext().error("Failed to register bean definition with name '" +
13                         bdHolder.getBeanName() + "'", ele, ex);
14             }
15             // Send registration event.
16             getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
17         }
18     }

  現在進入BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法進行分析:

 1 public static void registerBeanDefinition(
 2             BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
 3             throws BeanDefinitionStoreException {
 4 
 5         // Register bean definition under primary name.
 6         String beanName = definitionHolder.getBeanName();
 7         registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
 8 
 9         // Register aliases for bean name, if any.
10         String[] aliases = definitionHolder.getAliases();
11         if (aliases != null) {
12             for (String alias : aliases) {
13                 registry.registerAlias(beanName, alias);
14             }
15         }
16     }

  這裏的beanName就是之前封裝好的bean的id。這個方法中分別以id和別名作為key來註冊bean,其實就是存儲在map中。

  進入registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()),在其子類DefaultListableBeanFactory中有實現:

 1 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 2             throws BeanDefinitionStoreException {
 3 
 4         Assert.hasText(beanName, "Bean name must not be empty");
 5         Assert.notNull(beanDefinition, "BeanDefinition must not be null");
 6 
 7         if (beanDefinition instanceof AbstractBeanDefinition) {
 8             try {
 9                 ((AbstractBeanDefinition) beanDefinition).validate();
10             }
11             catch (BeanDefinitionValidationException ex) {
12                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
13                         "Validation of bean definition failed", ex);
14             }
15         }
16 
17         BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
18         if (existingDefinition != null) {
19             if (!isAllowBeanDefinitionOverriding()) {
20                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
21                         "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
22                         "': There is already [" + existingDefinition + "] bound.");
23             }
24             else if (existingDefinition.getRole() < beanDefinition.getRole()) {
25                 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
26                 if (logger.isWarnEnabled()) {
27                     logger.warn("Overriding user-defined bean definition for bean '" + beanName +
28                             "' with a framework-generated bean definition: replacing [" +
29                             existingDefinition + "] with [" + beanDefinition + "]");
30                 }
31             }
32             else if (!beanDefinition.equals(existingDefinition)) {
33                 if (logger.isInfoEnabled()) {
34                     logger.info("Overriding bean definition for bean '" + beanName +
35                             "' with a different definition: replacing [" + existingDefinition +
36                             "] with [" + beanDefinition + "]");
37                 }
38             }
39             else {
40                 if (logger.isDebugEnabled()) {
41                     logger.debug("Overriding bean definition for bean '" + beanName +
42                             "' with an equivalent definition: replacing [" + existingDefinition +
43                             "] with [" + beanDefinition + "]");
44                 }
45             }
46             this.beanDefinitionMap.put(beanName, beanDefinition);
47         }
48         else {
49             if (hasBeanCreationStarted()) {
50                 // Cannot modify startup-time collection elements anymore (for stable iteration)
51                 synchronized (this.beanDefinitionMap) {
52                     this.beanDefinitionMap.put(beanName, beanDefinition);
53                     List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
54                     updatedDefinitions.addAll(this.beanDefinitionNames);
55                     updatedDefinitions.add(beanName);
56                     this.beanDefinitionNames = updatedDefinitions;
57                     if (this.manualSingletonNames.contains(beanName)) {
58                         Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
59                         updatedSingletons.remove(beanName);
60                         this.manualSingletonNames = updatedSingletons;
61                     }
62                 }
63             }
64             else {
65                 // Still in startup registration phase
66                 this.beanDefinitionMap.put(beanName, beanDefinition);
67                 this.beanDefinitionNames.add(beanName);
68                 this.manualSingletonNames.remove(beanName);
69             }
70             this.frozenBeanDefinitionNames = null;
71         }
72 
73         if (existingDefinition != null || containsSingleton(beanName)) {
74             resetBeanDefinition(beanName);
75         }
76     }

  我們可以看到:這個beanDefinitionMap就是用來存儲解析好的bean的,以id作為key。至此,就將所有的bean標籤解析好之後封裝成BeanDefinition註冊到了IOC容器中。但是,到目前為止,IOC容器並沒有為我們將這些解析好的數據生成一個一個bean實例,我們仍然不能就這樣直接使用。下一篇接着跟蹤。

【精選推薦文章】

自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

【拆分版】Docker-compose構建Elasticsearch 7.1.0集群

1{icon} {views}

寫在前邊

搞了兩三天了,一直有個問題困擾着我,ES集群中配置怎麼能正確映射到主機上,這邊經常報ClusterFormationFailureHelper master not discovered or elected yet.原因是容器中的ES節點沒有正確的映射到主機上,而且容器內ip是易變的,我該怎麼配置呢?

臨下班了,終於想到個法子,固定容器ip——使用network_mode: host

看到主機模式的我眼前一亮,容器就相當於一個主機服務,你占哪個端口就是哪個,沒有必要再去自己指定port去映射到主機。這樣只要主機ip不變,容器中ip不就沒問題了么!!!

本文內容架構圖

解釋:

Master節點作為Master節點與協調節點,為防止腦裂問題,降低負載,不存數據

Node1~Node3為數據節點,不參與Master競選

TribeNode節點不存數據,不參與Master競選

準備環境

  • GNU/Debain Stretch 9.9 linux-4.19
  • Docker 18.09.6
  • Docker-Compose 1.17.1
  • elasticsearch:7.1.0

配置腳本參見我的Github <https://github.com/hellxz/docker-es-cluster.git>

宿主機環境準備參考ELK集群搭建,基於7.1.1 文中開始搭建的前四步

目錄結構

.
├── docker-es-data01
│   ├── data01
│   ├── data01-logs
│   ├── docker-compose.yml
│   ├── .env
│   └── es-config
│       └── elasticsearch.yml
├── docker-es-data02
│   ├── data02
│   ├── data02-logs
│   ├── docker-compose.yml
│   ├── .env
│   └── es-config
│       └── elasticsearch.yml
├── docker-es-data03
│   ├── data03
│   ├── data03-logs
│   ├── docker-compose.yml
│   ├── .env
│   └── es-config
│       └── elasticsearch.yml
├── docker-es-master
│   ├── docker-compose.yml
│   ├── .env
│   ├── es-config
│   │   └── elasticsearch.yml
│   ├── master-data
│   └── master-logs
└── docker-es-tribe
    ├── docker-compose.yml
    ├── .env
    ├── es-config
    │   └── elasticsearch.yml
    ├── tribe-data
    └── tribe-logs

最終效果

各目錄代表節點與端口號

節點目錄 節點名稱 協調端口號 說明 查詢端口號
docker-es-data01 data01 9301 數據節點1,非master節點 9201
docker-es-data02 data02 9302 數據節點2,非master節點 9202
docker-es-data03 data03 9303 數據節點3,非master節點 9203
docker-es-master master 9300 master節點,非數據節點 9200
docker-es-tribe tribe 9304 協調節點,非master非數據節點 9204

想測試這些節點是否可用,只需要修改每個節點目錄下的es-config/elasticsearch.yml中的ip地址,全部換成你需要的ip即可。

各文件功用舉例說明

鑒於這裏邊有很多是重複操作,這裏僅拿其中的master節點進行舉例,其餘代碼參見Github

.env 這個文件為docker-compose.yml提供默認參數,方便修改

# the default environment for es-master
# set es node jvm args
ES_JVM_OPTS=-Xms256m -Xmx256m
# set master node data folder
MASTER_DATA_DIR=./master-data
# set master node logs folder
MASTER_LOGS_DIR=./master-logs

docker-compose.yml docker-compose的配置文件

version: "3"
services:
    es-master:
        image: elasticsearch:7.1.0
        container_name: es-master
        environment: # setting container env
            - ES_JAVA_OPTS=${ES_JVM_OPTS}   # set es bootstrap jvm args
        restart: always
        volumes:
            - ./es-config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
            - ${MASTER_DATA_DIR}:/usr/share/elasticsearch/data:rw
            - ${MASTER_LOGS_DIR}:/usr/share/elasticsearch/logs:rw
        network_mode: "host"

簡單來說,就是修改pull的鏡像,替換其中的變量與配置文件,掛載數據與日誌目錄,最後用的host主機模式,讓節點服務佔用到實體機端口

elaticsearch.yml elasticsearch的配置文件,搭建集群最關鍵的文件之一

# ======================== Elasticsearch Configuration =========================
cluster.name: es-cluster
node.name: master 
node.master: true
node.data: false
node.attr.rack: r1 
bootstrap.memory_lock: true 
http.port: 9200
network.host: 10.2.114.110
transport.tcp.port: 9300
discovery.seed_hosts: ["10.2.114.110:9301","10.2.114.110:9302","10.2.114.110:9303","10.2.114.110:9304"] 
cluster.initial_master_nodes: ["master"] 
gateway.recover_after_nodes: 2

按照前幾篇文章下來,大家對這些參數已經不是很陌生了,這裏簡單說下幾個比較重要的參數

  • transport.tcp.port 設置es多節點協調的端口號
  • discovery.seed_hosts 設置當前節點啟動后要發現的協調節點位置,當然自己不需要發現自己,推薦使用ip:port形式,集群形成快
  • cluster.initial_master_nodes 集群中可以成為master節點的節點名,這裏指定唯一的一個,防止腦裂

使用說明

  1. 若想將此腳本使用到生產上,需要修改每個節點下的.env文件,將掛載數據、日誌目錄修改為啟動es的集群的用戶可讀寫的位置,可以通過sudo chmod 777 -R 目錄sudo chown -R 當前用戶名:用戶組 目錄 來修改被掛載的目錄權限
  2. 修改.env下的JVM參數,擴大堆內存,啟動與最大值最好相等,以減少gc次數,提高效率
  3. 修改所有節點下的docker-compose.yml 中的network.host地址 為當前所放置的主機的ip,discovery.seed_hosts需要填寫具體各待發現節點的實體機ip,以確保可以組成集群
  4. 確保各端口在其宿主機上沒有被佔用,如有佔用需確認是否有用,無用kill,有用則更新docker-compose.ymlhttp.porttransport.tcp.port,注意與此同時要更新其它節點的discovery.seed_hosts對應的port
  5. 如果在同一台主機上,可以參考使用文章後邊的簡單的shell腳本

各節點操作命令

後台啟動命令均為docker-compose up -d

關閉命令:

  • docker-compose down: 關閉同時移除容器與多餘虛擬網卡
  • docker stop contains_name: 根據容器名稱關閉容器,不移除容器

簡單的Shell腳本

docker-es-cluster-up.sh

#/bin/bash
# please put this shell script to the root of each node folder.
# this shell script for start up the docker-es-cluster designed in the one of linux server.
cd docker-es-master && docker-compose up -d && \
cd ../docker-es-data01 && docker-compose up -d && \
cd ../docker-es-data02 && docker-compose up -d && \
cd ../docker-es-data03 && docker-compose up -d && \
cd ../docker-es-tribe && docker-compose up -d && \
cd ..

docker-es-cluster-down.sh

#/bin/bash
# please put this shell script to the root of each node folder.
# this shell script for remove the docker-es-cluster's containers and networks designed in the one of linux server.
cd docker-es-tribe && docker-compose down && \
cd ../docker-es-data03 && docker-compose down && \
cd ../docker-es-data02 && docker-compose down && \
cd ../docker-es-data01 && docker-compose down && \
cd ../docker-es-master && docker-compose down && \
cd ..

docker-es-cluster-stop.sh

#/bin/bash
# please put this shell script to the root of each node folder.
# this shell script for stop the docker-es-cluster's containers designed in the one of linux server.
docker stop es-tribe es-data03 es-data02 es-data01 es-master

如果你想讓這些腳本有執行權限,不妨試試sudo chmod +x *.sh

這些腳本中沒有使用sudo,如需要使用sudo才能啟動docker,請添加當前用戶到docker組

Enjoy.

本文系原創文章,禁止轉載。

【精選推薦文章】

智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

想知道網站建置、網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計及後台網頁設計

帶您來看台北網站建置台北網頁設計,各種案例分享

廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

來阿里有段時間了,談談這幾個月最真實的感受

1{icon} {views}

作者:黃小斜

文章來源:微信公眾號【程序員江湖】

 

閱讀本文大概需要 4 分鐘。

 

 

有段時間沒寫過原創了,想了各種理由,發現其實理由就一個,沒時間。

 

我來阿里,已經幾個月了。這段時間,最大的感受就是累。我是在今年的四月份加入阿里的。

 

當初我沒有參加阿里巴巴的實習,而是選擇了直接進行校園招聘,這也是因為當時我對實習的部門不感興趣,於是在校招的時候我就選擇了自己感興趣的部門,也就是現在我所在的螞蟻金服。

 

之前就聽說過阿里的工作強度,可能會比較大,但是,當我在真正來到這家公司的時候,才發現996,並不是虛言,這倒不是說制度上規定的 996 ,而是因為,你手上的工作,是很難做完的,所以導致你不得不用加班的方式來完成,996 最終的目的只有一個,就是你要把手上的工作做完,對其他人有一個交代。

 

剛來一個月的時候只其實我是非常不適應的,畢竟從學校到公司,整個變化是顛覆性的,雖然之前有過實習經歷,但是是比較划水的,和正式工作差別還是比較大的,第一個月大抵的狀態就是,每天九點多上班,晚上九點及以後下班,這是生活規律上的不適應。

 

除此之外,在工作上也會有一些不適應,雖然前期給我的活兒都比較的零散,只要求這裏修修補補,那裡加點東西。這倒是其次。

 

 

主要的原因還是因為我對業務線的研發流程不太了解,以及對大家在做的事情不太了解,這會導致我在工作上遇到很多困難。因為我會聽不懂大家在說什麼。所以第一個月,更多的是思考。

 

如何去提高自己的效率,如何去融入這個公司,如何去熟悉部門的業務和技術戰,自己感覺是一個比較外向的人,所以一旦有問題就會諮詢,我的同事,我的師兄。

 

阿里的師兄是一種文化。就像武俠小說里的同門師兄弟一樣,師兄會帶領着你去做那些工作,並且讓你去熟悉整個部門的一些事情。我的師兄是一個寡言少語的人,但是技術能力非常強,也很有責任心。他總是對總是對工作要求特別高,不放過任何一個問題,不漏掉任何一行問題代碼。

 

在第一個月的時間里。我學習了很多阿里巴巴的一些中間件技術。其實這些技術。在學校複習的時候,多少也聽說過一些,看過一些文章。只不過外面用的都是開源的東西,而在阿里內部,更多的是自研的產品,比如說,消息中間件,分佈式事務,數據庫中間件,等等等等。這些東西,在平時的學習和研發中,是經常會用到的,如果你在學校或者是在其他小公司,可能根本沒有機會接觸到這些東西。

 

 

作為一個Java工程師,在這家公司的職責可不止是寫代碼,你需要熟悉整個研發流程,從系統設計,代碼開發,測試聯調,發布上線,問題排查都是你的職責,其實這很鍛煉人,這也是為什麼加班會這麼多的原因,寫代碼只佔你日常工作的一小部分時間,你需要花更多時間在解決各類問題上。

 

阿里對校招生有一個培訓,不同部門可能不太一樣,螞蟻的培訓長達一個月,這個月應該也是我覺得成長最快,過得最快樂的一個月,其實無非就是上課,拓展和各類活動,這段時間認識了很多人,其中也有很多大牛,大家一起上課,一起做項目,同甘共苦度過一個月,這樣的經歷也是非常值得紀念的。

 

培訓結束后,我也開始承擔更多的工作,當自己逐漸習慣這種節奏之後,才感覺自己逐漸在融入這家公司,每次搞懂一個業務問題或者技術問題都會覺得自己在成長,當肩頭上承擔更多責任的時候,同時也承擔了更多壓力,如果不能調整好自己的心態,我想在這家公司是很難待久的。

 

可能你在其他互聯網公司也會感受到相似的壓力,但這就是大部分互聯網公司的現狀,追求效率,追求極致,我們身在其中,就必須適應環境,尊重遊戲規則,馬上又是新一年的校招季,去年這個時候,這個公眾號才剛剛誕生,轉眼一年時間,多的是更多思考,希望公眾號的文章對你們有會有更多幫助。

 

下一篇文章應該也不會讓你們等太久。

 

 

文能碼字,武能coding,是我黃小斜,不是黃老邪噢。

 

 

推薦閱讀:

 

焦慮的 BAT、不安的編程語言,揭秘程序員技術圈生存現狀!

 

 

 

為什麼有些大公司技術弱爆了?

 

 

 

  

 

​你點的每個好看,我都認真當成了喜歡

【精選推薦文章】

如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

想要讓你的商品在網路上成為最夯、最多人討論的話題?

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師"嚨底家"!!

距離地球6光年的巴納德星b或支持原始生命

2{icon} {views}

  科技日報北京 1 月 15 日電 (記者劉霞)據英國《獨立報》近日報道,美國科學家聲稱,地球的鄰居之一——被稱為巴納德星b的超級地球可能比之前認為的更宜居,或許可成為原始生命的家園。

  巴納德星是距離太陽第二近的恆星系統,距地球 6 光年,巴納德星b是其中的一顆行星。去年 11 月,科學家宣布發現巴納德星b,但認為它可能不適合任何生命生存,因為其擁有一個冰冷的沙漠,沒有液態水,“陽光”非常微弱,且最低溫度可能為-170℃,足以殺死任何生命。

  但維拉諾瓦大學天體物理學家愛德華·吉南和斯科特·恩格爾近日表示,巴納德星b可能擁有一個巨大的、由鐵和鎳組成的地核,也有地熱活動,因此,它可能比之前想象的更宜居。

  吉南解釋說:“地熱加熱可使地表之下變為‘生命區’,類似於南極洲的地下湖泊。我們注意到,木星的冰凍衛星木衛二的表面溫度與巴納德星b相似,但由於潮汐加熱,木衛二冰凍的表面下可能存在液態海洋。”

  據悉,巴納德星的年齡約為 90 億歲,約為太陽年齡(46 億歲)的 2 倍;巴納德星b的質量是地球質量的 3 倍,公轉周期為 233 天,與其主恆星的距離大致相當於水星與太陽之間的距離。

  研究人員希望能對這顆行星進行更多研究,以更好地了解它的大氣、表面情況和潛在的宜居性。

  恩格爾說:“發現巴納德星b最重要的意義在於,這樣的行星可能比我們以為的更普遍,可能還有很多這樣的行星等待人類去發現。開普勒望遠鏡提供的數據表明,行星在整個銀河系中非常普遍,潛伏於銀河系各處的行星甚至可能有數百億顆。”

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

帶您來了解什麼是 USB CONNECTOR  ?

為什麼 USB CONNECTOR 是電子產業重要的元件?

又掌控什麼技術要點? 帶您認識其相關發展及效能

圍剿“老齡”微信

2{icon} {views}

  文/古泉君

  在快如科技發布會接近尾聲時,羅永浩說到:“歷史會記住這一天。”這當然不是因為時隔兩個多月羅永浩終於再次公開露面,而是因為在這一天,三款新發布的社交 App,先後被微信封殺,無一倖免。“出師未捷身先被封”,羅永浩和自如科技甚至專門做了一個網頁來紀念這個特殊的時刻,順便讓微信徹底成了壟斷的反派。

  王欣的“馬桶 MT”、字節跳動的“多閃”以及羅永浩的“聊天寶(子彈短信)”這三款新應用組成的“復讎者聯盟”,通過各種各樣的方式,把武器都對準了強大的“滅霸“微信。

  於是,微信打了一個響指……

  馬桶 MT:用“匿名”攻擊微信的“偉光正”

  很多網友都在微博上喊欠“快播一個會員”,出獄后王欣第一個創業項目也因此備受關注。馬桶 MT 也是今天第一個發布的產品。

  馬桶 MT 主打“匿名社交”,這並不是一個新鮮的玩法,此前“無秘”“秘密”“秘密圈”等產品都是火過一段時間后迅速消亡。

  馬桶 MT 相較上面這幾款產品,玩法要更多一些,紅包、朋友圈、群聊、付費問答等等功能合而為一,但這也增加了使用和理解的成本。

  不過,馬桶 MT 也是今天發布的幾款產品中最坎坷的一個,從今天上午開始,無法收到驗證碼、驗證碼錯誤的情況頻繁發生,而即便進入了應用內,用戶數也少得可憐,讓新用戶一時間沒打體驗到這款應用到底是用來做什麼的。

  更重要的是,匿名社交與附近的人功能結合,就勢必會滋生不良內容,人性如此。當初微信用戶數獲得知數增長,也是因為附近的人與搖一搖的加入,讓用戶看到了通過其完成某些“現下社交活動”的可能。而如今,微信已經“洗白”,更多的被應用到了工作場合,變得”偉光正“。而這,也許就是馬桶瞄準的機會。

  也因此,馬桶 MT 是最有可能遭遇監管麻煩的那個,但壞消息是,王欣入獄四年,可能已經不太適應如今的監管環境了。

  王欣在微博上曾說道“微信比你想象的更強大,所以熟人社交不要碰,但匿名熟人社交可以”,選擇匿名社交,是王欣在微信近乎壟斷的情況下,選擇的突破口。但匿名社交死了一輪又一輪,王欣的個人光環能否給馬桶加分,還未可知。

  多閃:微信不夠“親密”?

  多閃可能是相對最靠譜的一個,不僅有抖音的日活、字節跳動強大的產品能力做背書,更因為它確實和微信不能完全算是同類產品。

  微信坐擁 10 億用戶,想讓這 10 億人中每一個人都滿意是不可能的事。於是,任何一個用戶吐槽的點,都有可能成為一個所謂的創業方向。

  於是,多閃主打的就是“年輕”和“親密關係”。年輕是表象,親密關係才是實質。如今的微信,確實被大量的無效關係牽絆,微信也意識到了這個問題,7.0 推出的“時刻視頻”,就是要通過多一步的操作,篩選出真正關心你的朋友。

  而多閃更進一步,它可以和查看你視頻的用戶直接發起聊天,而“我想你了”等功能,也是在為親密關係開路,摒棄掉那些“表面之交”,至於擴大關係網,保持一些基本的聯繫,那是微信的事。

  而無法點贊、評論的設定,也淡化了多閃的“社交”屬性,強化了“表達”屬性。總之,在多閃的預期中,那些年輕人們礙於種種原因,不好意思、無法發在朋友圈的內容,都可以發在多閃上,然後基於內容的延伸話題,與最親密的好友保持聯繫。

  總體來說,還是避開了微信的鋒芒,今日頭條 CEO 的那句並不只是公關話術,微信發展至今,其氣質已經定型,想指望它短時間內發生翻天覆地的變化並不現實,而小部分用戶的額外需求,就成了多閃們的目標。

  聊天寶:赤裸裸的金錢誘惑

  子彈短信走的是另外一條路——赤裸裸的金錢誘惑。

  子彈短信上線之時,外界最大的質疑就是她無法撬動微信穩定的關係鏈,因此再多所謂方便的特性(這點也存疑)也是白搭。今天發布會,子彈短信繼續更新,帶來了一些新的特性,比如視頻回復、生朋友和熟朋友、掃碼和二維碼同時展示、新的表情、附近的人等等,這些都還是“癢點”的更新,這讓它看起來非常像一個民間魔改版微信,依然沒能解決最本質的問題。

  於是,升級后的聊天寶,帶來了一個看似複雜,其實簡單粗暴的解法——赤裸裸的金錢誘惑,具體的玩法和趣頭條們類似,用戶在聊天、看新聞、購物(拼多多)、玩遊戲等過程中都能拿到收益,羅永浩認為這是個很自然的過程,因為互聯網經歷了“收費—免費—補貼”這樣的發展過程,如今用錢砸出新用戶,是普遍採取的手段。

  另外,子彈短信也聯合移動和飛信,推出了通過短信,一鍵邀請所有通訊錄好友的功能,但這個功能很有可能會被當做垃圾短信而投訴的。

  接下來的一個小時,就成了聊天寶的“招商大會”,聊天寶推出了脫胎於“支付寶集五福”的“送換奪”的玩法,總之就是通過與大疆、三隻松鼠等廠商合作的營銷活動,用戶通過一系列的互動操作后能領取獎品。現場甚至放出了郵箱,在線招商。

  總之,這些都是聊天寶拉新的手段,產品方面,子彈短信還是那個子彈短信。

  但是,除非聊天寶能用這點錢撬動所有微信用戶,將社交關係完全遷移到這個新平台上,否則,靠這點蠅頭小利,依然難以撼動微信。實際上子彈短信已經不想做出差異化了,而是想通過擦邊球來挖微信牆角,但真正效果存疑——可能你老家的表弟會下載使用,但你的老闆會不會用,不太好說。

  另外,聊天寶也很可能會遇到監管的麻煩——首先,大規模給用戶群發短信,本身就是一件非常打擾的事情,很可能會被當作垃圾短信舉報;其次,羅永浩公開在發布會上介紹“送換奪”規則時稱“反正我們有你的身份證號嘛”,雖然侵犯用戶隱私在互聯網企業中見怪不怪,但這樣大張旗鼓地說出來,多少有些太過招搖,另外聊天這種付費推廣的模式也確實違反了微信的運營規則,不屏蔽你也是心太大了。

  高處不勝寒

  在國內,微信毫無疑問已經不只是“國民應用”級別了,它是移動互聯網本身,是功能機時代的電話與短信。正如微信革了短信的命一樣,暗處亦有人蠢蠢欲動,想革微信的命。微信的發展太過順利,甚至夢幻得有些不可思議,正如王欣接受採訪所說“天下苦微信久矣”,但凡是社交,總免不了和微信的比較。

  今天這三家移動社交的“復讎者聯盟”,很難說沒有互相借勢的成分。這其中,有人選擇通過匿名社交,或是主打年輕人的方式避免正面競爭,走差異化路線;而有的,則是通過簡單粗暴的補貼,公開挖微信的牆角。

  微信已經 8 歲了,此前它幾乎沒有遇到過像樣的挑戰者。如今,用戶經過一段時間的使用,已經逐漸明確了微信的槽點,而這,也會成為微信被攻擊的首要目標。高處不勝寒,微信的挑戰者永遠不會少。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【精選推薦文章】

平板收購,iphone手機收購,二手筆電回收,二手iphone收購-全台皆可收購

收購3c,收購IPHONE,收購蘋果電腦-詳細收購流程一覽表

高價3c回收,收購空拍機,收購鏡頭,收購 MACBOOK-更多收購平台討論專區

3c收購,鏡頭 收購有可能以全新價回收嗎?

賣IPHONE,iPhone回收,舊換新!教你怎麼賣才划算?

揭秘:強化小空間視覺張力的方法

2{icon} {views}

揭秘:強化小空間視覺張力的方法

來自:www.zxdyw.com
日期:2009-07-05 16:57:43
如何進行小空間的改造,以達到視覺張力的效果,以下是小編整理出的10種改變小空間視覺的方法,以便小居室裝修的朋友參考。

    降低裝飾品的擺放高度
  少就是多的設計概念,從提出到風行,至今經久不衰,正是由於局部的“單調”才對比出整體的精彩和更加完整。
  在小空間的牆面要盡量留白,因為為了保障收納空間,房間中已經有很多高櫃,如果在空餘的牆面再掛些飾品或照片,就會在視覺上過於擁擠。如果覺得牆面缺乏裝飾而缺少情趣,可以選擇房間內主色調中的一個色彩的飾品或裝飾畫,一定要在色調上不要太出格,不要因為更多色彩的加入而讓空間雜亂。適當地降低飾品的擺放位置,讓它們處於人體站立時視線的水平位置之下,既能豐富空間情調,又能減少視覺障礙。

  恰當選用無框磨邊鏡面
  大家都知道,水銀鏡面是延伸和擴大空間的好材料;可是,如果用得太多了,或者使用的地方不合適,就會適得其反,要麼變成練功房,要麼成了高級化妝間。首先,鏡面忌諱用到房間的主體牆裝飾上,特別是不適宜大面積使用;其次,鏡面面積不應超過牆面面積的2/5;最後,鏡面的造型要選擇簡單的。還有一點要特別提醒大家,安裝結束后,邊口的打膠處理一定要乾淨整潔且牢固,這樣才美觀又安全。

    造型上以直線條為主
  室內設計是建築的延伸和發展,因為目前房屋結構以直線居多,所以在內部設計時為了求其統一和協調,多使用直線作為設計符號;再者直線線形特點本身單一純粹,不會特別引起視覺長時間的注意,同時也會給人以安靜、暢快、直爽的感覺。

  盡量少選用小塊狀材料
  在小空間中,尤其是廚房和衛生間,相對其他空間更有限,視覺更加擁擠,這時最好不要使用太小規格的瓷磚或者馬賽克,這樣會使邊線增加,給人眼花繚亂的感覺,無形中會縮小空間感覺;取而代之選擇鋼化玻璃或者環氧樹脂漆裝飾牆面,空間感整潔、明快、通透;頂部可以選擇防水石膏板加防水漆,加強和地面的整體協調作用,突出在面上的擴張力。

  房間頂部簡約處理
  古人常說:“不着一字,盡得風流。”簡約,除了可以按照字面意思理解以外,其實還可以把這一理念做進一步的強化和延伸——完全可以不做任何多餘的裝飾處理,只把功能做足即可,小戶型更要貫徹這一原則。
  
    吊頂是可以強化房間風格的一種裝飾手段,但它會佔有房間的一部分高度空間。現在大家都知道在小房子中不要做複雜的吊頂,甚至不做吊頂,但簡化頂部裝飾還可以簡化材料和顏色,不論房子的牆面採用何種裝飾材料或者顏色,頂面都最好選擇白色調,讓人們忽略房頂,這樣在視覺上也就起到延伸的作用。

    色調統一,以淺色調為主
  色彩在空間里起着巨大作用,特別是對於小空間,在視覺局促的情況下,牆面色彩的選擇最為重要,因為進入空間里,直接看到的就是牆面了,而且牆體的面積最大,對視覺的影響也最大。
  地面和頂面甚至大規格的傢具、飾品也同樣需要和牆面相協調。色調要保持統一,比如有暖色調,如紅、橙黃;冷色調,如藍靛;還有中性色,如綠和紫以及無彩色系,如金、銀和黑白灰。淺,通常指色彩的明度和純度。

  選用柔和質感為主的裝修材料
  著名的建築大師安藤忠雄,就特別善於利用材料的質感做作品,尤其是在常人眼裡特別平常的材料的巧妙運用,讓空間氛圍震撼人心!建築結構大放異彩!
  牆面材料的選擇上,質感特別關鍵,小的空間並不一定只是選擇單一的塗料或金屬、磚等硬性材料。柔和質感材料,如壁紙,既可以很好地烘托房間氣氛,又可以陪襯房間內的傢具飾品,弱化空間的層次感,從而讓空間更加開闊。

  恰當地製作少量通透隔斷
  選擇恰當的位置設計小體量的隔斷裝飾,簡潔明快的隔斷會反襯出空間似隔非隔的效果,例如,造型可以是小方格或者是其他簡單線條的重複,色彩可以選擇啞光或者烤漆白給人以單薄、簡潔、通透的印象;隔斷的正面面積最好不超過牆面面積的1/5,比例和尺度是反映空間效果是否舒服的要素,它也是衡量專業設計師設計功底的重要依據。

  多採用側光源間接照明
  由於小空間里比較局促,層高又相對較矮,所以盡可能減少選擇天花大型燈具直接照明的方式,多選擇側光源間接照明方式,把燈具隱藏起來,起到見光不見燈的效果,這樣會把更多更大的空間感釋放出來。

    傢具要選擇淺調、透明或者體量較小的產品
  在小戶型中,傢具的佔地面積最好不要超過地面面積的1/6,傢具的材料可以適當選擇一些透明或者半透明的材質,傢具的體量能夠滿足使用要求即可。
  
    比如沙發,可以選擇只有坐墊和靠背,而無扶手的款式,看上去會輕巧得多;再如電視櫃的選用,其實一塊挑板擺放必要的音響就足矣,從立面看是線的造型,簡潔明快;柜子盡量選擇有櫃門的,這樣在視覺上更完整。

上述內容為轉載或編者觀點,不代表裝一網意見,不承擔任何法律責任。如侵權請聯繫刪除。


相關推薦

  • 空氣凈化器

延伸閱讀

  • 家裝市場競爭白熱化 期待行業協會強化管理
  • 30坪空間不敗設計裝潢 引誘你的視覺魅力
  • 精美閣樓卧室改造方案 時尚美觀增大視覺空間
  • 2009年複合地板-強化地板十大品牌
  • 揭秘:廚房用具的保養清潔方法
  • 看“面子”工程 選購適宜強化地板
  • 強化木地板選購和鑒別秘籍全攻略
  • 揭秘:廚房瓷磚選購的五大方法
  • 用了E0級板材真的環保嗎?來看看E0級板材甲醛釋放量多少

  • 硅藻泥怎麼施工?五分鐘教你學會硅藻泥施工步驟

  • 進門鞋櫃怎麼裝修最合理?裝修網列舉圖片來說明

  • 5平米小餐廳怎麼裝修好看?裝修網分享餐廳裝修設計技巧

本站聲明:網站內容來源於裝修網http://www.zhuangyi.com/,如有侵權,請聯繫我們

【室內裝潢設計廠商推薦】

新屋購入,尋找台中室內設計師?是否可先免費估價丈量?

想要打造簡約、淡雅兼且收納空間的小資房,台中室內設計推薦哪一家?

中古屋大改造,分享台中室內設計公司隔間重新規劃,擴大實用空間!

家裝秘笈:七招打造新鮮複式優雅家

5{icon} {views}

家裝秘笈:七招打造新鮮複式優雅家

來自:www.zxdyw.com
日期:2009-07-07 12:02:51
複式房現代主義風格要求住宅周圍應該保持與大自然的接觸,住宅內應該能滿足日常生活的需要。它熱忱地接受自然色彩,並用自然色彩來營造空間的氣氛。它對自然的重新關注,要求的不只是單純地應用天然材料,還應該要有寬闊的視野,讓自然景觀成為室內的一景,讓室內充滿自然光線。 

    複式房現代主義風格要求住宅周圍應該保持與大自然的接觸,住宅內應該能滿足日常生活的需要。它熱忱地接受自然色彩,並用自然色彩來營造空間的氣氛。它對自然的重新關注,要求的不只是單純地應用天然材料,還應該要有寬闊的視野,讓自然景觀成為室內的一景,讓室內充滿自然光線。

                    

    樓上看看樓下裝修風格,自然清新,給人俯視一切的感受,這也是複式與眾不同之處。

                   

    超大床給人有着夢寐以求歸來的感覺,一開門便想躺在床上休息片刻,體驗家的溫馨。

                   

    以簡單明了的直線條設計和特殊的空間感為特色,表達出自然與簡潔的風格,同時又融入幾何曲線,以現代、動感的形態迎合著人們的個性化需要。

                        

    晚上開燈便可忙碌一下白天沒有完成的事情,你會感到有着與辦公室不一樣的感受。

                       

    樓下的布藝沙發,、茶几、餐台椅無處不透漏出現代年輕人嚮往的那種浪漫和年輕。

                        

    從客廳看洗手間,你會感受到家的灑脫和安逸。

                            

    這樣的洗手間,乾淨清爽,色調和諧,正是我們年輕一代所嚮往的風格。

 

 

 

 

 

 

上述內容為轉載或編者觀點,不代表裝一網意見,不承擔任何法律責任。如侵權請聯繫刪除。


相關推薦

  • 複式樓梯裝修
  • 小複式公寓裝修
  • 複式改造
  • 倒複式裝修
  • 美式裝修風格樣板間
  • 歐式裝修風格
  • 開放式廚房
  • 開放式廚房好不好
  • 開放式書房
  • 步入式衣帽間
  • 開放式衣帽間
  • 歐式客廳
  • 換鞋凳式鞋櫃
  • 歐式電視背景牆
  • 掛壁式魚缸
  • 分離式衛生間
  • 哥特式裝修風格
  • 上海裝修公司哪家好
  • 重慶裝修公司哪家好
  • 廣州裝修公司哪家好
  • 深圳裝修公司哪家好
  • 武漢裝修公司哪家好

延伸閱讀

  • 木門窗裝修驗收 hold住的5招秘笈
  • 200平米美式風格複式樓裝修 打造明亮活力美家
  • 3階段省錢秘笈 教您做好家裝酷“摳”族
  • 家裝瓷磚用量計算秘笈 讓您自己算個明白賬
  • 愛家也要愛之有道 教你快速美化居家秘笈
  • 別小看家裝燈具 挑選“秘笈”不練真不行
  • 裝修網分享防坑寶典4大秘笈 專治各種家裝痛點
  • 仿若置身樹蔭之下悠然徜徉 複式別墅設計展現優雅
  • 用了E0級板材真的環保嗎?來看看E0級板材甲醛釋放量多少

  • 硅藻泥怎麼施工?五分鐘教你學會硅藻泥施工步驟

  • 進門鞋櫃怎麼裝修最合理?裝修網列舉圖片來說明

  • 5平米小餐廳怎麼裝修好看?裝修網分享餐廳裝修設計技巧

本站聲明:網站內容來源於裝修網http://www.zhuangyi.com/,如有侵權,請聯繫我們

【磁磚設計與裝修美學相關資訊】

挑好磚一點都不難!馬賽克磚挑選眉角小撇步!

浴室設計小心機,利用馬賽克磁磚,放大你的浴室空間

想改變客廳裝潢風格嗎? 馬賽克拼貼打造溫馨鄉村風,教你如何運用馬賽克瓷磚自行DIY創作
 

梅雨季節裝修過八關 專家為您出謀划策

2{icon} {views}

梅雨季節裝修過八關 專家為您出謀划策

來自:www.zxdyw.com
日期:2009-07-07 17:42:55
近日,持續降臨幾場暴雨,給炎熱的夏天帶來了一陣清爽涼意。老天爺像是用這幾場雨給大家提個醒,目前已經正式邁入了梅雨季季節,依然有很多業主裝修正在進行中。梅雨季節裝修應當注意什麼呢?

    第一關:木製品“變形記”

    關鍵詞:含水率

    板材對含水率的要求十分挑剔,既不能太高,也不宜過低,廈門地區一般以12%為佳。梅雨季節木製品的含水率往往高於這個百分比,這樣在乾燥季節容易出現木製品開裂、起翹等現象。

    專家支招:施工前晾乾木製品

選購人造板材時,首先要選“新鮮出爐”的產品,也就是近幾個月生產出來的,這樣的木製品經過了乾燥處理,接觸潮濕空氣的時間相對更少,含水率不高。與此相反,選擇木龍骨類材料時,則最好選擇“陳品”,而且沒有在露天存放過的,這樣的龍骨含水率會低一些。施工前,最好把木製品包裝打開晾一會,讓材料和室內的含水率接近。

    第二關:油漆“白化記”

    關鍵詞:白化水

    在雨季施工,可能會造成油漆發白。牆面容易形成水汽,刷漆、刮膩子也都不容易乾燥。當膩子沒有干透就進行油漆噴塗時,也容易出現問題,比如造成日後起泡、開裂等現象。

    專家支招:漆內調入白化水

    刷漆盡量避開雨天,如果無法避開,那就要多通風,等第一遍刷完干透后,再刷第二遍。此外,可在油漆中加入白化水調和劑等,加速乾燥。在牆面刮膩子前,可用干布將潮濕水汽擦乾。

    第三關:有害物質“揮發記”

    關鍵詞:通風

    在雨季時,由於氣壓比較低,許多有害物質會殘留在室內或裝飾裝修材料之中,不容易揮發。

    專家支招:保持室內良好的通風

    陰雨天時不僅空氣潮濕,而且室內空氣流動也比較緩慢,因此施工中要將所有的門窗都打開,以保持室內良好的通風。這樣不僅有利於施工人員的身體健康,而且有助於室內牆面、地面及木材等的儘早乾燥。

    第四關:電線“短路記”

    關鍵詞:包裹線頭

    在雨天裝修時,陽台等地方的電線容易被雨淋,會造成線路短路等問題。

    專家支招:裸露銅線頭包好防短路

    電路改造現在都採用套管埋線施工,不存在安全問題。但要注意將露在電線外的銅線頭包好,以防止電線受潮后短路。尤其對於環繞在受潮的木龍骨、大芯板等木製品周圍的電線要特別注意。

    第五關:牆面“起殼記”

    關鍵詞:干透

    專家支招:如果是新砌牆,則提前進場施工,給新牆面充分的乾燥時間,並做好基層的封閉;牆面也要提前批嵌,目的還是要讓它充分乾燥,前一層批嵌未乾透之前,絕不能批第二遍;選用適合的批嵌材料,石膏板接縫採用同質量材料批嵌;適當採取人工方法來加速乾燥;牆面漆要選用得當,盡量少用奶黃、深色的牆面漆。

    第六關:地板“起翹記”

    關鍵詞:防潮膜

    專家支招:鋪設地板的水泥地坪要保持乾燥,乾濕交界處要採用有效的隔斷處理方法。鋪地板時應採用防潮膜以便隔離潮氣,地板鋪設完工后,有條件的宜在隱蔽處留透氣孔。要根據地板樹種、含水率及空氣濕度來決定鋪設工藝,穩定性差的樹種需開包平衡時間長達72小時。

    第七關:木門“拆裝記”

    關鍵詞:封閉包裝

    專家支招:要使黃梅天安裝的木門套、木門不變形,需要烘乾木材,控制木材的含水率。木門出廠時要全封閉包裝,到現場拆封后即封閉處理。飾面板應予封閉保護或在黃梅天過後再貼。

    第八關:吊頂“開裂記”

    關鍵詞:錯位接縫

    專家支招:要防止吊頂開裂,需選用質優石膏板,盡量不在雨天運輸。運送途中要全封閉包裝,以控制石膏板含水率。石膏板縫隙不得小於0.5-0.8毫米,並採用同質量材料批嵌。吊頂龍骨連接處與石膏板接縫要錯位。

 

 

上述內容為轉載或編者觀點,不代表裝一網意見,不承擔任何法律責任。如侵權請聯繫刪除。


相關推薦

  • 玄關裝修
  • 進門玄關裝修
  • 玄關櫃
  • 玄關鞋櫃
  • 玄關是什麼
  • 玄關隔斷
  • 客廳玄關
  • 門口玄關
  • 馬賽克玄關
  • 玄關裝飾畫
  • 裝修風格
  • 裝修風格大全
  • 裝修風格分類
  • 裝修風格圖片
  • 裝修風格有哪些
  • 美式裝修風格樣板間
  • 歐式裝修風格
  • 裝修預算
  • 裝修預算表
  • 裝修預算清單
  • 家庭裝修預算
  • 80平米裝修預算
  • 90平米裝修預算
  • 100平米裝修預算

延伸閱讀

  • 梅雨季節可以裝修嗎 雙防傢具助您一臂之力
  • 梅雨季節裝修全攻略 多雨裝修不用談雨色變
  • 透析:梅雨季節傢具呵護“避暑”勢在必行
  • 又一年梅雨季節將至 教你木地板如何防潮
  • 梅雨季節如何防潮 木地板保養更要勤清潔
  • 梅雨季節如期而至 牆紙發霉原因及處理辦法須知
  • 梅雨季節來臨 木材市場總體行情很難表現上升跡象
  • 2012年春季裝修需要過六關 要重視細節
  • 用了E0級板材真的環保嗎?來看看E0級板材甲醛釋放量多少

  • 硅藻泥怎麼施工?五分鐘教你學會硅藻泥施工步驟

  • 進門鞋櫃怎麼裝修最合理?裝修網列舉圖片來說明

  • 5平米小餐廳怎麼裝修好看?裝修網分享餐廳裝修設計技巧

本站聲明:網站內容來源於裝修網http://www.zhuangyi.com/,如有侵權,請聯繫我們

【居家裝修精選推薦】

想知道北部最多平價、庫存出清的家具工廠推薦在哪裡?

屬於你的居家品味,家具訂製工廠推薦與心得分享

打造北歐風,連設計師也極力讚許的古典家具推薦工廠

好評熱賣,復刻家具推薦首選口袋名單

裝潢省錢妙招,家具訂製推薦達人,教您省下不必要的裝潢

家具設計推薦設計師,評論常見十大居家設計風格
 

居室色彩斑斕非好事 家裝務必要避開7中顏色(組圖)

2{icon} {views}

居室色彩斑斕非好事 家裝務必要避開7中顏色(組圖)

來自:www.zxdyw.com
日期:2009-07-08 10:21:49
家中漆粉紅色者,最為大凶之色,粉紅色易使人心情暴躁,易發生口角,爭是非、吵架之事頻繁;尤其新婚夫婦,為了調節閨中氣氛,在凡夫人眼中看來是極有羅曼蒂克的,但是,隨着色調的不調和,過一段時間後,兩人心情會產生莫名其妙的心火,容易為芝麻小事吵不完,最後走上離婚不歸路。設計師們應該注意,最好不用此色,此種色調也會造成神經病。

                      

    家中漆粉紅色者,最為大凶之色,粉紅色易使人心情暴躁,易發生口角,爭是非、吵架之事頻繁;尤其新婚夫婦,為了調節閨中氣氛,在凡夫人眼中看來是極有羅曼蒂克的,但是,隨着色調的不調和,過一段時間後,兩人心情會產生莫名其妙的心火,容易為芝麻小事吵不完,最後走上離婚不歸路,今日的社會離婚率這麽驚人,與此因素也佔了很大,所以,設計師們應該注意,最好不用此色,此種色調也會造成神經病。

                                    

    家中全部深藍色的,時間久了,家中會無形中產生陰氣沉沉,個個生性消極,家內也欠平安。

                          

    家中油漆紫色多者,雖然可說是紫氣滿室香,可惜紫色中所代有的紅色系列,無形中發出刺眼的色感,易使居家的人心有一種無奈感覺。

                      

    家中漆綠色多者,也是會使居家者意志漸消沉,並非一般所說的,眼睛應多接綠色,事實上,綠色是指大自然之綠色,而非人為之調配綠色,所以,難免會造成室內死氣沉沉,沒有生氣蓬勃。

                          

     家中紅色多者,中國人總是認為紅色是吉祥色,但韓國習俗死人家中用紅色布代表,這些都只是人的生活習俗而已,但是紅色系列多者,使人眼睛之負擔過重,而且使人的心情容易暴躁,所以,紅色只可做為搭配之少部份色調,不可做為主題之色調,但是佛寺廟宇則與住家不同。

                          

    家中漆黃多者,心情悶憂,煩熱不安,有一種說不出來得的驚、憂感覺,因此使人的腦神經意識充滿着多層幻覺,有的神經病者最忌此色了。

                             

    橘紅色多者,雖然是充滿生氣勃勃,很有溫暖的感覺,但是過多的橘色,也會使人心生厭煩的感覺。

上述內容為轉載或編者觀點,不代表裝一網意見,不承擔任何法律責任。如侵權請聯繫刪除。


相關推薦

  • 客廳窗帘什麼顏色好
  • 卧室顏色
  • 窗帘顏色選擇
  • 水電改造圖
  • 樓梯平面圖
  • 瓷磚貼圖
  • 舊房改造裝修對比圖

延伸閱讀

  • 打造色彩斑斕的兒童小天地(組圖)
  • 09家居色彩搭配流行趨勢 “紅、黃、藍”為主色調(組圖)
  • 純美白色系家居 用色彩點綴出生活的韻味(組圖)
  • 優雅古典家居 令居室氣質生輝(組圖)
  • 地毯是居室的點睛之筆 4個經典案例賞析(組圖)
  • 非主流牆紙設計締造色彩人生(圖)
  • 流行的家居色彩 裝一網推薦最in牆面顏色裝修效果圖
  • 避開家裝中的這五個禁區 原來你的家也可以這麼美
  • 用了E0級板材真的環保嗎?來看看E0級板材甲醛釋放量多少

  • 硅藻泥怎麼施工?五分鐘教你學會硅藻泥施工步驟

  • 進門鞋櫃怎麼裝修最合理?裝修網列舉圖片來說明

  • 5平米小餐廳怎麼裝修好看?裝修網分享餐廳裝修設計技巧

本站聲明:網站內容來源於裝修網http://www.zhuangyi.com/,如有侵權,請聯繫我們

【裝潢房事討論區】

解決漏水、壁癌危機,找尋新竹舊屋翻新專業修繕專家

老舊房屋馬桶不通、水管阻塞,推薦竹北通水管新竹通水管專業師傅,徹底解決多年臭味問題

針對一般住家各種奇怪漏水問題,竹北水電東通水管修復作業案例揭密!

推薦竹東裝潢老師傅統包團隊,裝潢、修繕一次搞定!!