Explication détaillée des idées de configuration de programmation Java-Tutoriel JavaEE

不言
Libérer: 2023-03-22 17:58:02
original
1623 Les gens l'ont consulté

Cet article partage principalement avec vous une explication détaillée des idées de configuration de programmation Java. J'espère qu'il sera utile aux amis qui apprennent Java

Explication détaillée des idées de configuration de programmation Java

Bien que SpringBoot fournit beaucoup d'excellents démarreurs nous aident à nous développer rapidement, mais en raison de la particularité de l'environnement de production actuel, nous devons encore personnaliser la configuration d'intégration par défaut pour améliorer la contrôlabilité du programme, bien que votre configuration ne soit peut-être pas meilleure que celle du démarreur officiel. . La semaine dernière, pour des raisons de travail et de décoration, le blog n'a pas été mis à jour normalement. J'avais peur qu'arrêter la mise à jour rende les gens paresseux, alors j'ai pris un peu de temps et j'ai écrit un article relativement simple. Plus tard, je parlerai de mon expérience depuis que je suis novice en décoration jusqu'à mes débuts.

Technologie : Configuration, ComponentScan, PropertySource, EnableTransactionManagement, Bean, Value
Remarque : Seul le code de configuration est publié dans l'article, le code de test complet est sur github supérieur.
Code source : https://github.com/ITDragonBl...
Structure du répertoire des articles :

Explication détaillée des idées de configuration de programmation Java-Tutoriel JavaEE

1. Configuration de la programmation Java

Avant Spring 4.x, la configuration XML était généralement utilisée dans la configuration de base des applications, et les annotations étaient recommandées dans la logique métier. Mais après Spring 4.x, les responsables ont commencé à recommander d'utiliser la configuration de programmation Java au lieu de la configuration XML. Pourquoi ? Quels sont les avantages et les inconvénients de ces deux configurations ?

Configuration de programmation Java et configuration XML

Avantages de la configuration XML : Pour nous, programmeurs d'ancienne génération (┬_┬), XML est très convivial, simple à utiliser, facile à développer et à modifier. Paramètres de configuration de l'application ne nécessitent pas de recompilation.

Inconvénients de la configuration XML : la lecture et l'analyse des fichiers de configuration prennent du temps, et les fichiers de configuration XML avec trop de contenu sembleront volumineux et peu pratiques à gérer.

Avantages de la configuration de programmation Java : par rapport à la configuration XML, sa structure est plus claire et plus lisible, et elle permet également de gagner du temps sur l'analyse XML.

Inconvénients de la configuration de la programmation Java : La modification des paramètres de configuration de l'application nécessite une recompilation. En fait, ce n'est pas un gros problème. Dans l'environnement de production actuel, une fois la configuration de l'application terminée, les gens ne la modifieront généralement pas et n'oseront pas la modifier à volonté.

Les deux ont leurs propres mérites. Étant donné que Spring4.x et SpringBoot recommandent d'utiliser la configuration de programmation Java, nous devrions également suivre la tendance du temps. Vous n'êtes pas obligé de l'utiliser, mais vous devez le comprendre. !

Étapes de configuration de la programmation Java

Étape 1 : Créer une classe de configuration, ajouter l'annotation Configuration au nom de la classe, informer Spring qu'il s'agit d'une classe de configuration, sa fonction est similaire à un fichier XML

Étape 2 : Chargez le fichier de configuration externe, ajoutez l'annotation PropertySource au nom de la classe et spécifiez le chemin de lecture du fichier de propriétés

Étape 3 : Obtenez la valeur de la propriété de configuration de l'application, ajoutez la valeur de l'annotation à la variable de propriété, et passez L'expression ${} obtient les paramètres dans le fichier de configuration

Étape 4 : Injection de dépendances, ajoutez des annotations Bean à la méthode, vous pouvez également utiliser FactoryBean

La syntaxe des première et quatrième étapes, La deuxième partie de l'article la présentera en détail. La syntaxe des deuxième et troisième étapes sera présentée en détail dans la troisième partie de l'article.

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * Spring 配置类
 * 配置数据源,事务管理,bean,自动扫描包
 * @author itdragon
 */
@Configuration    // 声明该类为配置类
@PropertySource({"classpath:propertySource.properties"})    // 引入外部文件
@ComponentScan("com.itdragon")    // 配置自动扫描包的路径
@EnableTransactionManagement    // 开启基于注解的事务管理功能
public class ApplicationContextConfig {
    
    @Value("${DATA_USER}")
    private String DATA_USER;
    
    @Value("${DATA_PAWD}")
    private String DATA_PAWD;
    
    @Value("${DATA_DRIVER}")
    private String DATA_DRIVER;
    
    @Value("${DATA_JDBC_URL}")
    private String DATA_JDBC_URL;
    
    @Bean // 数据源
    public DataSource dataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(DATA_USER);
        dataSource.setPassword(DATA_PAWD);
        dataSource.setDriverClass(DATA_DRIVER);
        dataSource.setJdbcUrl(DATA_JDBC_URL);
        return dataSource;
    }
    
    @Bean // jdbc模板
    public JdbcTemplate jdbcTemplate() throws Exception{
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }
    
    @Bean // 事务管理
    public PlatformTransactionManager transactionManager() throws Exception{
        return new DataSourceTransactionManager(dataSource());
    }

}
Copier après la connexion

Classe de transaction

import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itdragon.dao.ITDragonDao;

@Service
public class ITDragonServer {
    
    @Autowired(required=false)
    private ITDragonDao itdragonDao;

    public List<Map<String,Object>> findAll() {
        return itdragonDao.findAll();
    }
    
    @Transactional
    public void updateNameById(String name, Long id) {
        itdragonDao.updateUserNameById(name, id);
        System.out.println(0/0); // 事务异常
    }
}
Copier après la connexion

Pour le code complet, veuillez github asynchrone

2 Injection de composants

L'annotation du bean est similaire à < dans. la balise 🎜> du fichier xml, dans laquelle le nom de la méthode modifié par l'annotation Bean correspond à l'identifiant dans la balise <bean>. La valeur de l'id peut également être définie via l'attribut value de l'annotation Bean. Il est largement utilisé dans le code sous-jacent de SpringBoot. <bean>

Si vous souhaitez que l'objet soit créé après le démarrage du conteneur et obtenu directement du conteneur après utilisation, vous n'avez rien à faire, car Spring est une instance unique par défaut, c'est-à-dire l'objet est créé après le démarrage du conteneur et enregistré dans le conteneur, puis récupérez-le du conteneur lors de son utilisation.

Si vous souhaitez que le conteneur ne crée pas un objet après son démarrage, mais le crée lorsqu'il est utilisé, puis l'enregistre dans le conteneur, puis le récupère du conteneur la prochaine fois qu'il est utilisé , vous pouvez l'implémenter via un chargement différé, c'est-à-dire en utilisant le toilettage d'annotations différées.

Si vous souhaitez que le conteneur ne crée pas un objet après son démarrage, mais qu'il le crée à chaque fois qu'il est utilisé, utilisez la méthode multi-instance, c'est-à-dire utilisez l'annotation Scope et la valeur de le paramètre est prototype, c'est-à-dire @Scope("prototype") .

Si vous souhaitez sélectionner les beans qui doivent être injectés en fonction des conditions après le démarrage du conteneur, vous pouvez utiliser l'annotation Conditional pour juger que l'évaluation sous-jacente de SpringBoot utilise cette annotation.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Controller;
import com.itdragon.entity.ITDragonEntity;
import com.itdragon.server.ITDragonServer;

/**
 * 知识点二:配置自动扫描包路径
 * 一、注解ComponentScan的value值设置自动扫描包的路径
 * 二、注解ComponentScan的excludeFilters值设置扫描排除的规则
 *     1)、通过注解@Filter设置排除的类型,type=ANNOTATION表示按照注解包含排除。classes是具体的注解,如Controller,Server,Repository
 * 三、注解ComponentScan的includeFilters值设置扫描加入的规则
 *  1)、通过设置useDefaultFilters=false关闭Spring默认扫描全部的功能,使includeFilters生效
 *  
 * 知识点三:@Filter常用的拦截类型
 * 一、FilterType.ANNOTATION:按照注解
 * 二、FilterType.ASSIGNABLE_TYPE:按照给定的类型,包括其子类和实现类
 * 三、FilterType.CUSTOM:使用自定义规则
 * 
 * 第一个ComponentScan注解表示在指定包下不扫描通过Controller注解修饰的类和ITDragonServer类及其子类和实现类
 * 第二个ComponentScan注解表示在指定包下只扫描通过Controller注解修饰的类
 * 第三个ComponentScan注解表示在指定包下根据自定义拦截规则,不扫描满足规则的类
 */
@Configuration
@ComponentScan(value="com.itdragon",excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
        @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={ITDragonServer.class})})
//@ComponentScan(value="com.itdragon",includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class})},useDefaultFilters=false)
//@ComponentScan(value="com.itdragon",excludeFilters={@Filter(type=FilterType.CUSTOM,classes={ITDragonCustomTypeFilter.class})})
public class ITDragonConfig {
    
    /**
     * 知识点一:配置bean
     * 一、注解Bean的value值表示bean的id
     * 二、注解Bean的value值未设置,则方法名表示bean的id
     */
    @Bean(value="itdragonBean")
    public ITDragonEntity itdragonEntity() { //方法名很重要,类似xml的id名,也可以通过@bean的value值重定义
        return new ITDragonEntity("itdragon", "configuration-password", 25);
    }
    
    /**
     * 知识点四:Scope属性
     * @Scope,调整作用域,默认单实例
     * singleton:单实例:ioc容器启动后创建对象放到ioc容器中,需要是从容器中获取。
     * prototype:多实例:ioc容器启动后每次获取对象时都要创建对象。
     * request:同一次请求创建一个实例
     * session:同一个session创建一个实例
     * 
     * 知识点五:懒加载
     * 针对单实例而言,在容器启动后不创建对象,在第一次使用Bean时创建对象。可以理解为单实例的一种补充。
     * 
     */
//    @Scope("prototype")
    @Lazy
    @Bean
    public ITDragonEntity scopeTopicBean() {
        System.out.println("^^^^^^^^^^^^^^^^^^^^^Create Bean");
        return new ITDragonEntity("scopeBean", "singleton-prototype-request-session", 25);
    }
    
    /**
     * 知识点六:Conditional条件判断
     * 满足条件才会注册bean,可以修饰在类上,管理整个类下的组件注入。
     */
    @Bean
    @Conditional({ITDragonCustomCondition.class})
    public ITDragonEntity conditionalBean() {
        return new ITDragonEntity("conditionalBean", "Conditional-Condition-CustomCondition", 25);
    }
    
    /**
     * 知识点七:FactoryBean工厂Bean
     * FactoryBean默认通过调用getObject创建的对象,通过调用isSingleton设置单实例和多实例。
     */
    @Bean
    public ITDragonFactoryBean itdragonFactoryBean() {
        return new ITDragonFactoryBean();
    }
}
Copier après la connexion
Classe d'injection de composants de jugement conditionnel personnalisée

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * 自定义的条件判断组件注入
 * @author itdragon
 *
 */
public class ITDragonCustomCondition implements Condition{

    /**
     * 判断注册的bean中是否含有指定的bean
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 获取bean的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        return registry.containsBeanDefinition("scopeTopicBean"); // 有则加载conditionalBean
    }

}
Copier après la connexion
Classe d'usine Bean personnalisée

import org.springframework.beans.factory.FactoryBean;
import com.itdragon.entity.ITDragonEntity;
/**
 * 自定义Bean的工厂类
 * @author itdragon
 *
 */
public class ITDragonFactoryBean implements FactoryBean<ITDragonEntity>{

    public ITDragonEntity getObject() throws Exception {
        System.out.println("^^^^^^^^^^^^^^^^^^^^^FactoryBean Create Bean");
        return new ITDragonEntity(); // 创建对象并返回到容器中
    }

    public Class<?> getObjectType() {
        return ITDragonEntity.class;
    }

    public boolean isSingleton() {
        return false; // 设置多实例,true则为单例
    }

}
Copier après la connexion
Attribution d'attributs

Étapes d'affectation de propriété :

Étape 1 : Introduisez les fichiers externes via l'annotation PropertySource. Plusieurs peuvent être introduits. Si vous craignez que le fichier n'existe pas, vous pouvez l'ignorer en définissant le paramètre ignoreResourceNotFound

Étape 2 : Obtenez la valeur du fichier externe via l'annotation Value, généralement en utilisant l'attribut Value. Format ${}, et prend également en charge #{} Les expressions SpEL peuvent également être transmises directement sous forme de chaînes. Si vous souhaitez recevoir des valeurs complexes, telles que des collections, vous pouvez envisager d'utiliser l'annotation ConfigurationProperties. Les avantages et les inconvénients des deux seront présentés en détail plus tard.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.itdragon.entity.ITDragonEntity;

/**
 * 知识点一: 引入外部文件,并从文件中获取值
 * @PropertySource 引入外部文件,支持多个,如果文件不存在会报错,可以通过设置参数ignoreResourceNotFound=true忽略
 * @Value 从外部文件中获取值,支持spel表达式,#{},${},string
 * @author itdragon
 */
@Configuration
@PropertySource(value={"classpath:propertySource.properties","classpth:xxx.properties"},ignoreResourceNotFound=true)
public class ITDragonConfigValue {
    
    @Value("${ACCOUNT}")        // 从配置文件获取数据
    private String ACCOUNT;
    
    @Value("${PASSWORD}")
    private String PASSWORD;
    
    @Value("${AGE}")
    private Integer AGE;
    
    @Value("ITDragon")            // 普通赋值
    private String str;
    
    @Value("#{(1+2-3)/4*5}")    // 算术运算
    private String operator;
    
    @Value("#{1>2 || 2 <= 3}")    // 关系运算
    private Boolean comparison;
    
    @Value("#{systemProperties[&#39;java.version&#39;]}") // 系统配置:os.name
    private String systemProperties;
    
    @Value("#{T(java.lang.Math).abs(-18)}")    // 表达式
    private String mapExpression;
    
    @Bean("valueBean")
    public ITDragonEntity itdragonEntity() {
        System.out.println("^^^^^^^^^^^^^^^^^^^^ str : " + str);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ operator : " + operator);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ comparison : " + comparison);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ systemProperties : " + systemProperties);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ mapExpression : " + mapExpression);
        return new ITDragonEntity(ACCOUNT, PASSWORD, AGE);
    }

}
Copier après la connexion

四、闲谈学习

这里并不是介绍如何学习一门技术,而是论养成一个学习习惯的重要性。大一时期,因为担心找不到工作而报了一个线上培训机构。经常被洗脑,其中一句话而我印象深刻 ---- "让优秀成为一种习惯"。听得我热血沸腾。花了五六千大洋报名,后来才发现网上有免费的。。。。个人不建议参加培训

这钱花的还算值得,"让优秀成为一种习惯",这句话对我的影响很大,从大学到工作,每当遇到陌生的知识,并没有选择逃避它。而是抽时间从网上找资料,去学习,整理,实践直到弄懂它。可我万万没有想到,这种学习的精神竟然用到了装修上。。。。可能学习已经是我的一个习惯了吧

开始,我是一个装修小白,不知道什么是全包、半包、清包;不知道什么是硬装、软装;也不知道装修的流程;不知道水电线、橱柜、洁具的品牌选择,不知道挂机、柜机、风管机、中央空调的优缺点;不知道封阳台的利弊;更不知道一个装修效果图要七八千。面对这些未知的领域,我寸步难行。我清楚的知道:如果你不懂,你就是砧板上的鱼肉,任人宰割。

现在,我通过在百度,知乎,兔巴兔等平台上找答案,并把内容用Markdown的格式整理!我都被自己吓到了。不仅如此,我还在抢设计师的饭碗,自己动手设计效果图。在制作效果图的过程中,发现了很多不合理的设想。庆幸问自己设计了一套效果图,不然又有很多无用功,耗时,耗力,耗钱。爸妈和女票就是客户,而我就一直处于改!改!改!的阶段。体验了一把前端工程师的辛酸。

我是谁?我在哪?我在做什么?

我是一名程序员,我在学习的道路上,我在做能提高自己的事情!


相关推荐:



Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal