Most minor mode will define some custom key bindings of their own. Most of time they have a keymap variable with the name modename-mode-map. For example, help-mode-map for Emacs Help system, flyspell-mode-map for spell checker. Most of the time they are works fine. But some of them will conflict with my global keybindings.

For example, the flyspell-mode has keymap definition like this

 
  (defvar flyspell-mode-map
    (let ((map (make-sparse-keymap)))
      (if flyspell-use-meta-tab
        (define-key map "\M-\t" 'flyspell-auto-correct-word))
      (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
      (define-key map [(control ?\,)] 'flyspell-goto-next-error)
      (define-key map [(control ?\.)] 'flyspell-auto-correct-word)
      (define-key map [?\C-c ?$] 'flyspell-correct-word-before-point)
      map)
    "Minor mode keymap for Flyspell mode--for the whole buffer.")
 
 

I already defined C-c as coping text.

 
 (global-set-key "\C-c" 'kill-ring-save)
 

When enable flyspell mode with "M-x flyspell-mode" command. The global set key binding C-c will be overwrite. I know how to add new key bindings to a minor mode map:

 
;; add or rewrite minor map key binding
(add-hook 'ielm-mode-hook
  (lambda ()
     (define-key ielm-map (kbd "<return>") 'ielm-return)))
 

See Rebind Ctrl-m and Enter in Emacs

But how to disable a minor mode key binding? You see the "defvar flyspell-mode-map" is always executed when loading flyspell-mode. So redefine the minor mode key map aren't gonna work.

 
(add-hook 'flyspell-mode-hook
  (lambda ()
  (defvar flyspell-mode-map
    (let ((map (make-sparse-keymap)))
      (if flyspell-use-meta-tab
        (define-key map "\M-\t" 'flyspell-auto-correct-word))
      (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
      (define-key map [(control ?\,)] 'flyspell-goto-next-error)
      (define-key map [(control ?\.)] 'flyspell-auto-correct-word)
      ;(define-key map [?\C-c ?$] 'flyspell-correct-word-before-point)
      map)
    "Minor mode keymap for Flyspell mode--for the whole buffer.")
  )
)
 

We comment out the key binding which conflict with us. It won't work because in flyspell.el it will be redefined again. Do a global key set also not work:

 
(add-hook 'flyspell-mode-hook
  (lambda ()
  (defvar flyspell-mode-map
    (let ((map (make-sparse-keymap)))
      (if flyspell-use-meta-tab
        (define-key map "\M-\t" 'flyspell-auto-correct-word))
      (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
      (define-key map [(control ?\,)] 'flyspell-goto-next-error)
      (define-key map [(control ?\.)] 'flyspell-auto-correct-word)
      ;(define-key map [?\C-c ?$] 'flyspell-correct-word-before-point)
      map)
    "Minor mode keymap for Flyspell mode--for the whole buffer.")
     (global-set-key "\C-c" 'kill-ring-save)
  )
)
 

If we look at the documentation of global-set-key: M-x describe-function global-set-key.

Note that if KEY has a local binding in the current buffer, that local binding will continue to shadow any global binding that you make with this function.

At the end, I find the answer, but its unexpected, the right way is to redefine C-c in the minor mode key map, it still gonna shadowing the global binding, but with our command.

 
(add-hook 'flyspell-mode-hook
  (lambda ()
     (define-key flyspell-mode-map  "\C-c" 'kill-ring-save)
  )
)
 

This resolve my problem, but the better solution I want is prevent the minor mode from defining particular key binding at all.